@walkeros/server-destination-bing 3.4.1 → 4.0.0-next-1777463920154

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/dist/dev.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,o=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},n={};o(n,{examples:()=>S,schemas:()=>s}),module.exports=(e=n,((e,o,n,s)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let d of r(o))i.call(e,d)||d===n||t(e,d,{get:()=>o[d],enumerable:!(s=a(o,d))||s.enumerable});return e})(t({},"__esModule",{value:!0}),e));var s={};o(s,{AdStorageConsentSchema:()=>v,EventTypeSchema:()=>l,MappingSchema:()=>g,SettingsSchema:()=>p,mapping:()=>y,settings:()=>h});var d=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),p=c.z.object({accessToken:c.z.string().min(1).describe("Long-lived Bing UET CAPI access token from Microsoft Advertising"),tagId:c.z.string().min(1).describe("Microsoft Advertising UET tag ID"),url:c.z.string().url().describe("Custom Bing UET CAPI base URL (default https://capi.uet.microsoft.com/v1/)").optional(),doNotHash:c.z.array(c.z.string()).describe("User data fields to skip hashing (like ['em', 'ph'])").optional(),user_data:c.z.record(c.z.string(),c.z.string()).describe("Mapping for user data fields (like { em: 'user.email' })").optional(),dataProvider:c.z.string().describe('Identifier of the data source (default "walkerOS")').optional(),continueOnValidationError:c.z.boolean().describe("When true, Microsoft continues to ingest events despite validation errors").optional()}),u=require("@walkeros/core/dev"),m=require("@walkeros/core/dev"),l=m.z.enum(["pageLoad","custom"]),v=m.z.enum(["G","D"]),g=u.z.object({eventType:l.describe('Override event type: "pageLoad" for page views, "custom" (default) otherwise').optional()}),h=(0,d.zodToSchema)(p),y=(0,d.zodToSchema)(g),S={};o(S,{env:()=>f,step:()=>w});var f={};o(f,{push:()=>b,simulation:()=>T});var b={sendServer:async()=>({ok:!0,data:{status:"OK",requestId:"mock-123"}})},T=["sendServer"],w={};o(w,{addToCart:()=>A,lead:()=>P,pageView:()=>z,purchase:()=>E});var U=require("@walkeros/core"),O="https://capi.uet.microsoft.com/v1/UET-12345/events",k={headers:{Authorization:"Bearer s3cr3t","Content-Type":"application/json"}},E={title:"Purchase",description:"A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.",in:(0,U.getEvent)("order complete",{timestamp:17000009e5,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Widget Pro",price:124.99,quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"server",id:"https://shop.example.com/checkout/complete",previous_id:""}}),mapping:{name:"purchase",data:{map:{customData:{map:{value:"data.total",currency:{key:"data.currency",value:"EUR"},transactionId:"data.id",pageType:{value:"purchase"},items:{loop:["nested",{condition:e=>(0,U.isObject)(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}},userData:{map:{externalId:"user.id"}}}}},out:[["sendServer",O,JSON.stringify({data:[{eventType:"custom",eventId:"1700000900000-gr0up-1",eventTime:1700000900,adStorageConsent:"G",userData:{externalId:"user-123"},eventName:"purchase",eventSourceUrl:"https://shop.example.com/checkout/complete",customData:{value:249.99,currency:"EUR",transactionId:"ORD-300",pageType:"purchase",items:[{id:"SKU-A1",name:"Widget Pro",price:124.99,quantity:2}]}}],dataProvider:"walkerOS"}),k]]},z={title:"Page view",description:"A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.",in:(0,U.getEvent)("page view",{timestamp:1700000901e3,source:{type:"server",id:"https://example.com/docs/",previous_id:""}}),mapping:{settings:{eventType:"pageLoad"}},out:[["sendServer",O,JSON.stringify({data:[{eventType:"pageLoad",eventId:"1700000901000-gr0up-1",eventTime:1700000901,adStorageConsent:"G",userData:{},eventSourceUrl:"https://example.com/docs/"}],dataProvider:"walkerOS"}),k]]},P={title:"Lead",description:"A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.",in:(0,U.getEvent)("form submit",{timestamp:1700000902e3,data:{type:"newsletter"},user:{email:"user@example.com"},source:{type:"server",id:"https://example.com/contact",previous_id:""}}),mapping:{name:"lead",data:{map:{userData:{map:{em:"user.email"}}}}},out:[["sendServer",O,JSON.stringify({data:[{eventType:"custom",eventId:"1700000902000-gr0up-1",eventTime:1700000902,adStorageConsent:"G",userData:{em:"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514"},eventName:"lead",eventSourceUrl:"https://example.com/contact"}],dataProvider:"walkerOS"}),k]]},A={title:"Add to cart",description:"A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.",in:(0,U.getEvent)("product add",{timestamp:1700000903e3,data:{id:"SKU-B2",name:"Running Shoes",price:89.99,color:"blue"},nested:[{entity:"product",data:{id:"SKU-B2",name:"Running Shoes",price:89.99,quantity:1}}],source:{type:"server",id:"https://shop.example.com/products/running-shoes",previous_id:""}}),mapping:{name:"add_to_cart",data:{map:{customData:{map:{value:"data.price",currency:{value:"EUR"},items:{loop:["nested",{condition:e=>(0,U.isObject)(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}}}},out:[["sendServer",O,JSON.stringify({data:[{eventType:"custom",eventId:"1700000903000-gr0up-1",eventTime:1700000903,adStorageConsent:"G",userData:{},eventName:"add_to_cart",eventSourceUrl:"https://shop.example.com/products/running-shoes",customData:{value:89.99,currency:"EUR",items:[{id:"SKU-B2",name:"Running Shoes",price:89.99,quantity:1}]}}],dataProvider:"walkerOS"}),k]]};//# sourceMappingURL=dev.js.map
1
+ "use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,i=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},n={};i(n,{examples:()=>f,schemas:()=>s}),module.exports=(e=n,((e,i,n,s)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let d of r(i))o.call(e,d)||d===n||t(e,d,{get:()=>i[d],enumerable:!(s=a(i,d))||s.enumerable});return e})(t({},"__esModule",{value:!0}),e));var s={};i(s,{AdStorageConsentSchema:()=>v,EventTypeSchema:()=>l,MappingSchema:()=>g,SettingsSchema:()=>p,mapping:()=>y,settings:()=>h});var d=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),p=c.z.object({accessToken:c.z.string().min(1).describe("Long-lived Bing UET CAPI access token from Microsoft Advertising"),tagId:c.z.string().min(1).describe("Microsoft Advertising UET tag ID"),url:c.z.string().url().describe("Custom Bing UET CAPI base URL (default https://capi.uet.microsoft.com/v1/)").optional(),doNotHash:c.z.array(c.z.string()).describe("User data fields to skip hashing (like ['em', 'ph'])").optional(),user_data:c.z.record(c.z.string(),c.z.string()).describe("Mapping for user data fields (like { em: 'user.email' })").optional(),dataProvider:c.z.string().describe('Identifier of the data source (default "walkerOS")').optional(),continueOnValidationError:c.z.boolean().describe("When true, Microsoft continues to ingest events despite validation errors").optional()}),u=require("@walkeros/core/dev"),m=require("@walkeros/core/dev"),l=m.z.enum(["pageLoad","custom"]),v=m.z.enum(["G","D"]),g=u.z.object({eventType:l.describe('Override event type: "pageLoad" for page views, "custom" (default) otherwise').optional()}),h=(0,d.zodToSchema)(p),y=(0,d.zodToSchema)(g),f={};i(f,{env:()=>b,step:()=>T});var b={};i(b,{push:()=>S,simulation:()=>w});var S={sendServer:async()=>({ok:!0,data:{status:"OK",requestId:"mock-123"}})},w=["sendServer"],T={};i(T,{addToCart:()=>A,lead:()=>P,pageView:()=>z,purchase:()=>E});var U=require("@walkeros/core"),O="https://capi.uet.microsoft.com/v1/UET-12345/events",k={headers:{Authorization:"Bearer s3cr3t","Content-Type":"application/json"}},E={title:"Purchase",description:"A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.",in:(0,U.getEvent)("order complete",{id:"b1c2d3e4f5a60001",timestamp:17000009e5,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Widget Pro",price:124.99,quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"browser",platform:"web",url:"https://shop.example.com/checkout/complete"}}),mapping:{name:"purchase",data:{map:{customData:{map:{value:"data.total",currency:{key:"data.currency",value:"EUR"},transactionId:"data.id",pageType:{value:"purchase"},items:{loop:["nested",{condition:e=>(0,U.isObject)(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}},userData:{map:{externalId:"user.id"}}}}},out:[["sendServer",O,JSON.stringify({data:[{eventType:"custom",eventId:"b1c2d3e4f5a60001",eventTime:1700000900,adStorageConsent:"G",userData:{externalId:"user-123"},eventName:"purchase",eventSourceUrl:"https://shop.example.com/checkout/complete",customData:{value:249.99,currency:"EUR",transactionId:"ORD-300",pageType:"purchase",items:[{id:"SKU-A1",name:"Widget Pro",price:124.99,quantity:2}]}}],dataProvider:"walkerOS"}),k]]},z={title:"Page view",description:"A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.",in:(0,U.getEvent)("page view",{id:"b1c2d3e4f5a60002",timestamp:1700000901e3,source:{type:"browser",platform:"web",url:"https://example.com/docs/"}}),mapping:{settings:{eventType:"pageLoad"}},out:[["sendServer",O,JSON.stringify({data:[{eventType:"pageLoad",eventId:"b1c2d3e4f5a60002",eventTime:1700000901,adStorageConsent:"G",userData:{},eventSourceUrl:"https://example.com/docs/"}],dataProvider:"walkerOS"}),k]]},P={title:"Lead",description:"A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.",in:(0,U.getEvent)("form submit",{id:"b1c2d3e4f5a60003",timestamp:1700000902e3,data:{type:"newsletter"},user:{email:"user@example.com"},source:{type:"browser",platform:"web",url:"https://example.com/contact"}}),mapping:{name:"lead",data:{map:{userData:{map:{em:"user.email"}}}}},out:[["sendServer",O,JSON.stringify({data:[{eventType:"custom",eventId:"b1c2d3e4f5a60003",eventTime:1700000902,adStorageConsent:"G",userData:{em:"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514"},eventName:"lead",eventSourceUrl:"https://example.com/contact"}],dataProvider:"walkerOS"}),k]]},A={title:"Add to cart",description:"A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.",in:(0,U.getEvent)("product add",{id:"b1c2d3e4f5a60004",timestamp:1700000903e3,data:{id:"SKU-B2",name:"Running Shoes",price:89.99,color:"blue"},nested:[{entity:"product",data:{id:"SKU-B2",name:"Running Shoes",price:89.99,quantity:1}}],source:{type:"browser",platform:"web",url:"https://shop.example.com/products/running-shoes"}}),mapping:{name:"add_to_cart",data:{map:{customData:{map:{value:"data.price",currency:{value:"EUR"},items:{loop:["nested",{condition:e=>(0,U.isObject)(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}}}},out:[["sendServer",O,JSON.stringify({data:[{eventType:"custom",eventId:"b1c2d3e4f5a60004",eventTime:1700000903,adStorageConsent:"G",userData:{},eventName:"add_to_cart",eventSourceUrl:"https://shop.example.com/products/running-shoes",customData:{value:89.99,currency:"EUR",items:[{id:"SKU-B2",name:"Running Shoes",price:89.99,quantity:1}]}}],dataProvider:"walkerOS"}),k]]};//# 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/schemas/primitives.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 * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Long-lived Bing UET CAPI access token from Microsoft Advertising',\n ),\n tagId: z.string().min(1).describe('Microsoft Advertising UET tag ID'),\n url: z\n .string()\n .url()\n .describe(\n 'Custom Bing UET CAPI base URL (default https://capi.uet.microsoft.com/v1/)',\n )\n .optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"User data fields to skip hashing (like ['em', 'ph'])\")\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\"Mapping for user data fields (like { em: 'user.email' })\")\n .optional(),\n dataProvider: z\n .string()\n .describe('Identifier of the data source (default \"walkerOS\")')\n .optional(),\n continueOnValidationError: z\n .boolean()\n .describe(\n 'When true, Microsoft continues to ingest events despite validation errors',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\nimport { EventTypeSchema } from './primitives';\n\n/**\n * Bing UET CAPI Mapping Schema\n * Per-event overrides. Use `eventType: 'pageLoad'` for page view events.\n */\nexport const MappingSchema = z.object({\n eventType: EventTypeSchema.describe(\n 'Override event type: \"pageLoad\" for page views, \"custom\" (default) otherwise',\n ).optional(),\n});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Bing UET CAPI event type. `pageLoad` for page views, `custom` for all\n * other conversion events.\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nexport const EventTypeSchema = z.enum(['pageLoad', 'custom']);\n\n/**\n * adStorageConsent — `G` when granted, `D` when denied. Defaults to `G`\n * when the event reaches the destination (pre-filtered via consent rules).\n */\nexport const AdStorageConsentSchema = z.enum(['G', 'D']);\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for the Bing UET CAPI destination.\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\nconst mockSendServer: MockSendServer = async () => ({\n ok: true,\n data: {\n status: 'OK',\n requestId: 'mock-123',\n },\n});\n\n/**\n * Standard mock environment for push operations.\n *\n * Use this for testing Bing UET CAPI events without making actual HTTP\n * requests to Microsoft's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Bing UET CAPI step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.tagId}/events`\n * and `body = { data: [capiEvent], dataProvider }`.\n *\n * Test fixture pins `tagId = 'UET-12345'` and the default url, so every\n * endpoint resolves to:\n * https://capi.uet.microsoft.com/v1/UET-12345/events\n *\n * Body is emitted with keys in the order the destination assembles them:\n * 1. eventType\n * 2. eventId\n * 3. eventTime (unix seconds; `Math.round(event.timestamp / 1000)`)\n * 4. adStorageConsent\n * 5. userData (hashed — only `em`, `ph` via SHA-256)\n * 6. eventName (only when eventType === 'custom')\n * 7. eventSourceUrl (only when event.source.id is set)\n * 8. customData (only when it has keys)\n *\n * The `options` argument carries the Authorization + Content-Type headers.\n */\nconst ENDPOINT = 'https://capi.uet.microsoft.com/v1/UET-12345/events';\nconst OPTIONS = {\n headers: {\n Authorization: 'Bearer s3cr3t',\n 'Content-Type': 'application/json',\n },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.',\n in: getEvent('order complete', {\n timestamp: 1700000900000,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: { id: 'SKU-A1', name: 'Widget Pro', price: 124.99, quantity: 2 },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: {\n type: 'server',\n id: 'https://shop.example.com/checkout/complete',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'purchase',\n data: {\n map: {\n customData: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n transactionId: 'data.id',\n pageType: { value: 'purchase' },\n items: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n userData: {\n map: {\n externalId: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: '1700000900000-gr0up-1',\n eventTime: 1700000900,\n adStorageConsent: 'G',\n userData: {\n externalId: 'user-123',\n },\n eventName: 'purchase',\n eventSourceUrl: 'https://shop.example.com/checkout/complete',\n customData: {\n value: 249.99,\n currency: 'EUR',\n transactionId: 'ORD-300',\n pageType: 'purchase',\n items: [\n {\n id: 'SKU-A1',\n name: 'Widget Pro',\n price: 124.99,\n quantity: 2,\n },\n ],\n },\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.',\n in: getEvent('page view', {\n timestamp: 1700000901000,\n source: {\n type: 'server',\n id: 'https://example.com/docs/',\n previous_id: '',\n },\n }),\n mapping: {\n settings: { eventType: 'pageLoad' },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'pageLoad',\n eventId: '1700000901000-gr0up-1',\n eventTime: 1700000901,\n adStorageConsent: 'G',\n userData: {},\n eventSourceUrl: 'https://example.com/docs/',\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.',\n in: getEvent('form submit', {\n timestamp: 1700000902000,\n data: { type: 'newsletter' },\n user: { email: 'user@example.com' },\n source: {\n type: 'server',\n id: 'https://example.com/contact',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'lead',\n data: {\n map: {\n userData: {\n map: {\n em: 'user.email',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: '1700000902000-gr0up-1',\n eventTime: 1700000902,\n adStorageConsent: 'G',\n userData: {\n // sha256(normalizeEmail('user@example.com'))\n em: 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514',\n },\n eventName: 'lead',\n eventSourceUrl: 'https://example.com/contact',\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.',\n in: getEvent('product add', {\n timestamp: 1700000903000,\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n color: 'blue',\n },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n quantity: 1,\n },\n },\n ],\n source: {\n type: 'server',\n id: 'https://shop.example.com/products/running-shoes',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'add_to_cart',\n data: {\n map: {\n customData: {\n map: {\n value: 'data.price',\n currency: { value: 'EUR' },\n items: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: '1700000903000-gr0up-1',\n eventTime: 1700000903,\n adStorageConsent: 'G',\n userData: {},\n eventName: 'add_to_cart',\n eventSourceUrl: 'https://shop.example.com/products/running-shoes',\n customData: {\n value: 89.99,\n currency: 'EUR',\n items: [\n {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n quantity: 1,\n },\n ],\n },\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,cAA4B;;;ACA5B,iBAAkB;AAEX,IAAM,iBAAiB,aAAE,OAAO;AAAA,EACrC,aAAa,aACV,OAAO,EACP,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AAAA,EACF,OAAO,aAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,kCAAkC;AAAA,EACpE,KAAK,aACF,OAAO,EACP,IAAI,EACJ;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,WAAW,aACR,MAAM,aAAE,OAAO,CAAC,EAChB,SAAS,sDAAsD,EAC/D,SAAS;AAAA,EACZ,WAAW,aACR,OAAO,aAAE,OAAO,GAAG,aAAE,OAAO,CAAC,EAC7B,SAAS,0DAA0D,EACnE,SAAS;AAAA,EACZ,cAAc,aACX,OAAO,EACP,SAAS,oDAAoD,EAC7D,SAAS;AAAA,EACZ,2BAA2B,aACxB,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;ACnCD,IAAAC,cAAkB;;;ACAlB,IAAAC,cAAkB;AAOX,IAAM,kBAAkB,cAAE,KAAK,CAAC,YAAY,QAAQ,CAAC;AAMrD,IAAM,yBAAyB,cAAE,KAAK,CAAC,KAAK,GAAG,CAAC;;;ADNhD,IAAM,gBAAgB,cAAE,OAAO;AAAA,EACpC,WAAW,gBAAgB;AAAA,IACzB;AAAA,EACF,EAAE,SAAS;AACb,CAAC;;;AFDM,IAAM,eAAW,yBAAY,cAAc;AAC3C,IAAM,cAAU,yBAAY,aAAa;;;AIXhD;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAiBA,IAAM,iBAAiC,aAAa;AAAA,EAClD,IAAI;AAAA,EACJ,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,WAAW;AAAA,EACb;AACF;AAQO,IAAM,OAAY;AAAA,EACvB,YAAY;AACd;AAEO,IAAM,aAAa,CAAC,YAAY;;;ACnCvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAmC;AA0BnC,IAAM,WAAW;AACjB,IAAM,UAAU;AAAA,EACd,SAAS;AAAA,IACP,eAAe;AAAA,IACf,gBAAgB;AAAA,EAClB;AACF;AAEO,IAAM,WAA6B;AAAA,EACxC,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,kBAAkB;AAAA,IAC7B,WAAW;AAAA,IACX,MAAM,EAAE,IAAI,WAAW,OAAO,QAAQ,UAAU,MAAM;AAAA,IACtD,QAAQ;AAAA,MACN;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,EAAE,IAAI,UAAU,MAAM,cAAc,OAAO,QAAQ,UAAU,EAAE;AAAA,MACvE;AAAA,IACF;AAAA,IACA,MAAM,EAAE,IAAI,YAAY,QAAQ,aAAa;AAAA,IAC7C,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK;AAAA,QACH,YAAY;AAAA,UACV,KAAK;AAAA,YACH,OAAO;AAAA,YACP,UAAU,EAAE,KAAK,iBAAiB,OAAO,MAAM;AAAA,YAC/C,eAAe;AAAA,YACf,UAAU,EAAE,OAAO,WAAW;AAAA,YAC9B,OAAO;AAAA,cACL,MAAM;AAAA,gBACJ;AAAA,gBACA;AAAA,kBACE,WAAW,CAAC,eACV,sBAAS,MAAM,KAAK,OAAO,WAAW;AAAA,kBACxC,KAAK;AAAA,oBACH,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,OAAO;AAAA,oBACP,UAAU,EAAE,KAAK,iBAAiB,OAAO,EAAE;AAAA,kBAC7C;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,UAAU;AAAA,UACR,KAAK;AAAA,YACH,YAAY;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ;AAAA,YACE,WAAW;AAAA,YACX,SAAS;AAAA,YACT,WAAW;AAAA,YACX,kBAAkB;AAAA,YAClB,UAAU;AAAA,cACR,YAAY;AAAA,YACd;AAAA,YACA,WAAW;AAAA,YACX,gBAAgB;AAAA,YAChB,YAAY;AAAA,cACV,OAAO;AAAA,cACP,UAAU;AAAA,cACV,eAAe;AAAA,cACf,UAAU;AAAA,cACV,OAAO;AAAA,gBACL;AAAA,kBACE,IAAI;AAAA,kBACJ,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,UAAU;AAAA,gBACZ;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,WAA6B;AAAA,EACxC,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,aAAa;AAAA,IACxB,WAAW;AAAA,IACX,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,UAAU,EAAE,WAAW,WAAW;AAAA,EACpC;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ;AAAA,YACE,WAAW;AAAA,YACX,SAAS;AAAA,YACT,WAAW;AAAA,YACX,kBAAkB;AAAA,YAClB,UAAU,CAAC;AAAA,YACX,gBAAgB;AAAA,UAClB;AAAA,QACF;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,OAAyB;AAAA,EACpC,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM,EAAE,MAAM,aAAa;AAAA,IAC3B,MAAM,EAAE,OAAO,mBAAmB;AAAA,IAClC,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK;AAAA,QACH,UAAU;AAAA,UACR,KAAK;AAAA,YACH,IAAI;AAAA,UACN;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ;AAAA,YACE,WAAW;AAAA,YACX,SAAS;AAAA,YACT,WAAW;AAAA,YACX,kBAAkB;AAAA,YAClB,UAAU;AAAA;AAAA,cAER,IAAI;AAAA,YACN;AAAA,YACA,WAAW;AAAA,YACX,gBAAgB;AAAA,UAClB;AAAA,QACF;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,YAA8B;AAAA,EACzC,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,MACN;AAAA,QACE,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK;AAAA,QACH,YAAY;AAAA,UACV,KAAK;AAAA,YACH,OAAO;AAAA,YACP,UAAU,EAAE,OAAO,MAAM;AAAA,YACzB,OAAO;AAAA,cACL,MAAM;AAAA,gBACJ;AAAA,gBACA;AAAA,kBACE,WAAW,CAAC,eACV,sBAAS,MAAM,KAAK,OAAO,WAAW;AAAA,kBACxC,KAAK;AAAA,oBACH,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,OAAO;AAAA,oBACP,UAAU,EAAE,KAAK,iBAAiB,OAAO,EAAE;AAAA,kBAC7C;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,MAAM;AAAA,UACJ;AAAA,YACE,WAAW;AAAA,YACX,SAAS;AAAA,YACT,WAAW;AAAA,YACX,kBAAkB;AAAA,YAClB,UAAU,CAAC;AAAA,YACX,WAAW;AAAA,YACX,gBAAgB;AAAA,YAChB,YAAY;AAAA,cACV,OAAO;AAAA,cACP,UAAU;AAAA,cACV,OAAO;AAAA,gBACL;AAAA,kBACE,IAAI;AAAA,kBACJ,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,UAAU;AAAA,gBACZ;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,cAAc;AAAA,MAChB,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AACF;","names":["import_dev","import_dev","import_dev"]}
1
+ {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/schemas/primitives.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 * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Long-lived Bing UET CAPI access token from Microsoft Advertising',\n ),\n tagId: z.string().min(1).describe('Microsoft Advertising UET tag ID'),\n url: z\n .string()\n .url()\n .describe(\n 'Custom Bing UET CAPI base URL (default https://capi.uet.microsoft.com/v1/)',\n )\n .optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"User data fields to skip hashing (like ['em', 'ph'])\")\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\"Mapping for user data fields (like { em: 'user.email' })\")\n .optional(),\n dataProvider: z\n .string()\n .describe('Identifier of the data source (default \"walkerOS\")')\n .optional(),\n continueOnValidationError: z\n .boolean()\n .describe(\n 'When true, Microsoft continues to ingest events despite validation errors',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\nimport { EventTypeSchema } from './primitives';\n\n/**\n * Bing UET CAPI Mapping Schema\n * Per-event overrides. Use `eventType: 'pageLoad'` for page view events.\n */\nexport const MappingSchema = z.object({\n eventType: EventTypeSchema.describe(\n 'Override event type: \"pageLoad\" for page views, \"custom\" (default) otherwise',\n ).optional(),\n});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Bing UET CAPI event type. `pageLoad` for page views, `custom` for all\n * other conversion events.\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nexport const EventTypeSchema = z.enum(['pageLoad', 'custom']);\n\n/**\n * adStorageConsent — `G` when granted, `D` when denied. Defaults to `G`\n * when the event reaches the destination (pre-filtered via consent rules).\n */\nexport const AdStorageConsentSchema = z.enum(['G', 'D']);\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for the Bing UET CAPI destination.\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\nconst mockSendServer: MockSendServer = async () => ({\n ok: true,\n data: {\n status: 'OK',\n requestId: 'mock-123',\n },\n});\n\n/**\n * Standard mock environment for push operations.\n *\n * Use this for testing Bing UET CAPI events without making actual HTTP\n * requests to Microsoft's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Bing UET CAPI step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.tagId}/events`\n * and `body = { data: [capiEvent], dataProvider }`.\n *\n * Test fixture pins `tagId = 'UET-12345'` and the default url, so every\n * endpoint resolves to:\n * https://capi.uet.microsoft.com/v1/UET-12345/events\n *\n * Body is emitted with keys in the order the destination assembles them:\n * 1. eventType\n * 2. eventId\n * 3. eventTime (unix seconds; `Math.round(event.timestamp / 1000)`)\n * 4. adStorageConsent\n * 5. userData (hashed - only `em`, `ph` via SHA-256)\n * 6. eventName (only when eventType === 'custom')\n * 7. eventSourceUrl (only when event.source.url is set)\n * 8. customData (only when it has keys)\n *\n * The `options` argument carries the Authorization + Content-Type headers.\n */\nconst ENDPOINT = 'https://capi.uet.microsoft.com/v1/UET-12345/events';\nconst OPTIONS = {\n headers: {\n Authorization: 'Bearer s3cr3t',\n 'Content-Type': 'application/json',\n },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.',\n in: getEvent('order complete', {\n id: 'b1c2d3e4f5a60001',\n timestamp: 1700000900000,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: { id: 'SKU-A1', name: 'Widget Pro', price: 124.99, quantity: 2 },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/checkout/complete',\n },\n }),\n mapping: {\n name: 'purchase',\n data: {\n map: {\n customData: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n transactionId: 'data.id',\n pageType: { value: 'purchase' },\n items: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n userData: {\n map: {\n externalId: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: 'b1c2d3e4f5a60001',\n eventTime: 1700000900,\n adStorageConsent: 'G',\n userData: {\n externalId: 'user-123',\n },\n eventName: 'purchase',\n eventSourceUrl: 'https://shop.example.com/checkout/complete',\n customData: {\n value: 249.99,\n currency: 'EUR',\n transactionId: 'ORD-300',\n pageType: 'purchase',\n items: [\n {\n id: 'SKU-A1',\n name: 'Widget Pro',\n price: 124.99,\n quantity: 2,\n },\n ],\n },\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.',\n in: getEvent('page view', {\n id: 'b1c2d3e4f5a60002',\n timestamp: 1700000901000,\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/docs/',\n },\n }),\n mapping: {\n settings: { eventType: 'pageLoad' },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'pageLoad',\n eventId: 'b1c2d3e4f5a60002',\n eventTime: 1700000901,\n adStorageConsent: 'G',\n userData: {},\n eventSourceUrl: 'https://example.com/docs/',\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.',\n in: getEvent('form submit', {\n id: 'b1c2d3e4f5a60003',\n timestamp: 1700000902000,\n data: { type: 'newsletter' },\n user: { email: 'user@example.com' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/contact',\n },\n }),\n mapping: {\n name: 'lead',\n data: {\n map: {\n userData: {\n map: {\n em: 'user.email',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: 'b1c2d3e4f5a60003',\n eventTime: 1700000902,\n adStorageConsent: 'G',\n userData: {\n // sha256(normalizeEmail('user@example.com'))\n em: 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514',\n },\n eventName: 'lead',\n eventSourceUrl: 'https://example.com/contact',\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.',\n in: getEvent('product add', {\n id: 'b1c2d3e4f5a60004',\n timestamp: 1700000903000,\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n color: 'blue',\n },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n quantity: 1,\n },\n },\n ],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/products/running-shoes',\n },\n }),\n mapping: {\n name: 'add_to_cart',\n data: {\n map: {\n customData: {\n map: {\n value: 'data.price',\n currency: { value: 'EUR' },\n items: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: 'b1c2d3e4f5a60004',\n eventTime: 1700000903,\n adStorageConsent: 'G',\n userData: {},\n eventName: 'add_to_cart',\n eventSourceUrl: 'https://shop.example.com/products/running-shoes',\n customData: {\n value: 89.99,\n currency: 'EUR',\n items: [\n {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n quantity: 1,\n },\n ],\n },\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["import_dev","import_dev","import_dev"]}
package/dist/dev.mjs CHANGED
@@ -1 +1 @@
1
- var e=Object.defineProperty,t=(t,a)=>{for(var r in a)e(t,r,{get:a[r],enumerable:!0})},a={};t(a,{AdStorageConsentSchema:()=>c,EventTypeSchema:()=>d,MappingSchema:()=>p,SettingsSchema:()=>o,mapping:()=>u,settings:()=>m});import{zodToSchema as r}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";var o=i.object({accessToken:i.string().min(1).describe("Long-lived Bing UET CAPI access token from Microsoft Advertising"),tagId:i.string().min(1).describe("Microsoft Advertising UET tag ID"),url:i.string().url().describe("Custom Bing UET CAPI base URL (default https://capi.uet.microsoft.com/v1/)").optional(),doNotHash:i.array(i.string()).describe("User data fields to skip hashing (like ['em', 'ph'])").optional(),user_data:i.record(i.string(),i.string()).describe("Mapping for user data fields (like { em: 'user.email' })").optional(),dataProvider:i.string().describe('Identifier of the data source (default "walkerOS")').optional(),continueOnValidationError:i.boolean().describe("When true, Microsoft continues to ingest events despite validation errors").optional()});import{z as s}from"@walkeros/core/dev";import{z as n}from"@walkeros/core/dev";var d=n.enum(["pageLoad","custom"]),c=n.enum(["G","D"]),p=s.object({eventType:d.describe('Override event type: "pageLoad" for page views, "custom" (default) otherwise').optional()}),m=r(o),u=r(p),l={};t(l,{env:()=>v,step:()=>y});var v={};t(v,{push:()=>g,simulation:()=>h});var g={sendServer:async()=>({ok:!0,data:{status:"OK",requestId:"mock-123"}})},h=["sendServer"],y={};t(y,{addToCart:()=>A,lead:()=>w,pageView:()=>k,purchase:()=>b});import{getEvent as S,isObject as f}from"@walkeros/core";var T="https://capi.uet.microsoft.com/v1/UET-12345/events",U={headers:{Authorization:"Bearer s3cr3t","Content-Type":"application/json"}},b={title:"Purchase",description:"A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.",in:S("order complete",{timestamp:17000009e5,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Widget Pro",price:124.99,quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"server",id:"https://shop.example.com/checkout/complete",previous_id:""}}),mapping:{name:"purchase",data:{map:{customData:{map:{value:"data.total",currency:{key:"data.currency",value:"EUR"},transactionId:"data.id",pageType:{value:"purchase"},items:{loop:["nested",{condition:e=>f(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}},userData:{map:{externalId:"user.id"}}}}},out:[["sendServer",T,JSON.stringify({data:[{eventType:"custom",eventId:"1700000900000-gr0up-1",eventTime:1700000900,adStorageConsent:"G",userData:{externalId:"user-123"},eventName:"purchase",eventSourceUrl:"https://shop.example.com/checkout/complete",customData:{value:249.99,currency:"EUR",transactionId:"ORD-300",pageType:"purchase",items:[{id:"SKU-A1",name:"Widget Pro",price:124.99,quantity:2}]}}],dataProvider:"walkerOS"}),U]]},k={title:"Page view",description:"A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.",in:S("page view",{timestamp:1700000901e3,source:{type:"server",id:"https://example.com/docs/",previous_id:""}}),mapping:{settings:{eventType:"pageLoad"}},out:[["sendServer",T,JSON.stringify({data:[{eventType:"pageLoad",eventId:"1700000901000-gr0up-1",eventTime:1700000901,adStorageConsent:"G",userData:{},eventSourceUrl:"https://example.com/docs/"}],dataProvider:"walkerOS"}),U]]},w={title:"Lead",description:"A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.",in:S("form submit",{timestamp:1700000902e3,data:{type:"newsletter"},user:{email:"user@example.com"},source:{type:"server",id:"https://example.com/contact",previous_id:""}}),mapping:{name:"lead",data:{map:{userData:{map:{em:"user.email"}}}}},out:[["sendServer",T,JSON.stringify({data:[{eventType:"custom",eventId:"1700000902000-gr0up-1",eventTime:1700000902,adStorageConsent:"G",userData:{em:"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514"},eventName:"lead",eventSourceUrl:"https://example.com/contact"}],dataProvider:"walkerOS"}),U]]},A={title:"Add to cart",description:"A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.",in:S("product add",{timestamp:1700000903e3,data:{id:"SKU-B2",name:"Running Shoes",price:89.99,color:"blue"},nested:[{entity:"product",data:{id:"SKU-B2",name:"Running Shoes",price:89.99,quantity:1}}],source:{type:"server",id:"https://shop.example.com/products/running-shoes",previous_id:""}}),mapping:{name:"add_to_cart",data:{map:{customData:{map:{value:"data.price",currency:{value:"EUR"},items:{loop:["nested",{condition:e=>f(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}}}},out:[["sendServer",T,JSON.stringify({data:[{eventType:"custom",eventId:"1700000903000-gr0up-1",eventTime:1700000903,adStorageConsent:"G",userData:{},eventName:"add_to_cart",eventSourceUrl:"https://shop.example.com/products/running-shoes",customData:{value:89.99,currency:"EUR",items:[{id:"SKU-B2",name:"Running Shoes",price:89.99,quantity:1}]}}],dataProvider:"walkerOS"}),U]]};export{l as examples,a as schemas};//# sourceMappingURL=dev.mjs.map
1
+ var e=Object.defineProperty,t=(t,a)=>{for(var r in a)e(t,r,{get:a[r],enumerable:!0})},a={};t(a,{AdStorageConsentSchema:()=>c,EventTypeSchema:()=>d,MappingSchema:()=>p,SettingsSchema:()=>o,mapping:()=>u,settings:()=>m});import{zodToSchema as r}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";var o=i.object({accessToken:i.string().min(1).describe("Long-lived Bing UET CAPI access token from Microsoft Advertising"),tagId:i.string().min(1).describe("Microsoft Advertising UET tag ID"),url:i.string().url().describe("Custom Bing UET CAPI base URL (default https://capi.uet.microsoft.com/v1/)").optional(),doNotHash:i.array(i.string()).describe("User data fields to skip hashing (like ['em', 'ph'])").optional(),user_data:i.record(i.string(),i.string()).describe("Mapping for user data fields (like { em: 'user.email' })").optional(),dataProvider:i.string().describe('Identifier of the data source (default "walkerOS")').optional(),continueOnValidationError:i.boolean().describe("When true, Microsoft continues to ingest events despite validation errors").optional()});import{z as n}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";var d=s.enum(["pageLoad","custom"]),c=s.enum(["G","D"]),p=n.object({eventType:d.describe('Override event type: "pageLoad" for page views, "custom" (default) otherwise').optional()}),m=r(o),u=r(p),l={};t(l,{env:()=>v,step:()=>f});var v={};t(v,{push:()=>g,simulation:()=>h});var g={sendServer:async()=>({ok:!0,data:{status:"OK",requestId:"mock-123"}})},h=["sendServer"],f={};t(f,{addToCart:()=>A,lead:()=>k,pageView:()=>U,purchase:()=>T});import{getEvent as y,isObject as b}from"@walkeros/core";var S="https://capi.uet.microsoft.com/v1/UET-12345/events",w={headers:{Authorization:"Bearer s3cr3t","Content-Type":"application/json"}},T={title:"Purchase",description:"A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.",in:y("order complete",{id:"b1c2d3e4f5a60001",timestamp:17000009e5,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Widget Pro",price:124.99,quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"browser",platform:"web",url:"https://shop.example.com/checkout/complete"}}),mapping:{name:"purchase",data:{map:{customData:{map:{value:"data.total",currency:{key:"data.currency",value:"EUR"},transactionId:"data.id",pageType:{value:"purchase"},items:{loop:["nested",{condition:e=>b(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}},userData:{map:{externalId:"user.id"}}}}},out:[["sendServer",S,JSON.stringify({data:[{eventType:"custom",eventId:"b1c2d3e4f5a60001",eventTime:1700000900,adStorageConsent:"G",userData:{externalId:"user-123"},eventName:"purchase",eventSourceUrl:"https://shop.example.com/checkout/complete",customData:{value:249.99,currency:"EUR",transactionId:"ORD-300",pageType:"purchase",items:[{id:"SKU-A1",name:"Widget Pro",price:124.99,quantity:2}]}}],dataProvider:"walkerOS"}),w]]},U={title:"Page view",description:"A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.",in:y("page view",{id:"b1c2d3e4f5a60002",timestamp:1700000901e3,source:{type:"browser",platform:"web",url:"https://example.com/docs/"}}),mapping:{settings:{eventType:"pageLoad"}},out:[["sendServer",S,JSON.stringify({data:[{eventType:"pageLoad",eventId:"b1c2d3e4f5a60002",eventTime:1700000901,adStorageConsent:"G",userData:{},eventSourceUrl:"https://example.com/docs/"}],dataProvider:"walkerOS"}),w]]},k={title:"Lead",description:"A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.",in:y("form submit",{id:"b1c2d3e4f5a60003",timestamp:1700000902e3,data:{type:"newsletter"},user:{email:"user@example.com"},source:{type:"browser",platform:"web",url:"https://example.com/contact"}}),mapping:{name:"lead",data:{map:{userData:{map:{em:"user.email"}}}}},out:[["sendServer",S,JSON.stringify({data:[{eventType:"custom",eventId:"b1c2d3e4f5a60003",eventTime:1700000902,adStorageConsent:"G",userData:{em:"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514"},eventName:"lead",eventSourceUrl:"https://example.com/contact"}],dataProvider:"walkerOS"}),w]]},A={title:"Add to cart",description:"A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.",in:y("product add",{id:"b1c2d3e4f5a60004",timestamp:1700000903e3,data:{id:"SKU-B2",name:"Running Shoes",price:89.99,color:"blue"},nested:[{entity:"product",data:{id:"SKU-B2",name:"Running Shoes",price:89.99,quantity:1}}],source:{type:"browser",platform:"web",url:"https://shop.example.com/products/running-shoes"}}),mapping:{name:"add_to_cart",data:{map:{customData:{map:{value:"data.price",currency:{value:"EUR"},items:{loop:["nested",{condition:e=>b(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}}}},out:[["sendServer",S,JSON.stringify({data:[{eventType:"custom",eventId:"b1c2d3e4f5a60004",eventTime:1700000903,adStorageConsent:"G",userData:{},eventName:"add_to_cart",eventSourceUrl:"https://shop.example.com/products/running-shoes",customData:{value:89.99,currency:"EUR",items:[{id:"SKU-B2",name:"Running Shoes",price:89.99,quantity:1}]}}],dataProvider:"walkerOS"}),w]]};export{l as examples,a 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/schemas/primitives.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 * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Long-lived Bing UET CAPI access token from Microsoft Advertising',\n ),\n tagId: z.string().min(1).describe('Microsoft Advertising UET tag ID'),\n url: z\n .string()\n .url()\n .describe(\n 'Custom Bing UET CAPI base URL (default https://capi.uet.microsoft.com/v1/)',\n )\n .optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"User data fields to skip hashing (like ['em', 'ph'])\")\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\"Mapping for user data fields (like { em: 'user.email' })\")\n .optional(),\n dataProvider: z\n .string()\n .describe('Identifier of the data source (default \"walkerOS\")')\n .optional(),\n continueOnValidationError: z\n .boolean()\n .describe(\n 'When true, Microsoft continues to ingest events despite validation errors',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\nimport { EventTypeSchema } from './primitives';\n\n/**\n * Bing UET CAPI Mapping Schema\n * Per-event overrides. Use `eventType: 'pageLoad'` for page view events.\n */\nexport const MappingSchema = z.object({\n eventType: EventTypeSchema.describe(\n 'Override event type: \"pageLoad\" for page views, \"custom\" (default) otherwise',\n ).optional(),\n});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Bing UET CAPI event type. `pageLoad` for page views, `custom` for all\n * other conversion events.\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nexport const EventTypeSchema = z.enum(['pageLoad', 'custom']);\n\n/**\n * adStorageConsent — `G` when granted, `D` when denied. Defaults to `G`\n * when the event reaches the destination (pre-filtered via consent rules).\n */\nexport const AdStorageConsentSchema = z.enum(['G', 'D']);\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for the Bing UET CAPI destination.\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\nconst mockSendServer: MockSendServer = async () => ({\n ok: true,\n data: {\n status: 'OK',\n requestId: 'mock-123',\n },\n});\n\n/**\n * Standard mock environment for push operations.\n *\n * Use this for testing Bing UET CAPI events without making actual HTTP\n * requests to Microsoft's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Bing UET CAPI step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.tagId}/events`\n * and `body = { data: [capiEvent], dataProvider }`.\n *\n * Test fixture pins `tagId = 'UET-12345'` and the default url, so every\n * endpoint resolves to:\n * https://capi.uet.microsoft.com/v1/UET-12345/events\n *\n * Body is emitted with keys in the order the destination assembles them:\n * 1. eventType\n * 2. eventId\n * 3. eventTime (unix seconds; `Math.round(event.timestamp / 1000)`)\n * 4. adStorageConsent\n * 5. userData (hashed — only `em`, `ph` via SHA-256)\n * 6. eventName (only when eventType === 'custom')\n * 7. eventSourceUrl (only when event.source.id is set)\n * 8. customData (only when it has keys)\n *\n * The `options` argument carries the Authorization + Content-Type headers.\n */\nconst ENDPOINT = 'https://capi.uet.microsoft.com/v1/UET-12345/events';\nconst OPTIONS = {\n headers: {\n Authorization: 'Bearer s3cr3t',\n 'Content-Type': 'application/json',\n },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.',\n in: getEvent('order complete', {\n timestamp: 1700000900000,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: { id: 'SKU-A1', name: 'Widget Pro', price: 124.99, quantity: 2 },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: {\n type: 'server',\n id: 'https://shop.example.com/checkout/complete',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'purchase',\n data: {\n map: {\n customData: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n transactionId: 'data.id',\n pageType: { value: 'purchase' },\n items: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n userData: {\n map: {\n externalId: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: '1700000900000-gr0up-1',\n eventTime: 1700000900,\n adStorageConsent: 'G',\n userData: {\n externalId: 'user-123',\n },\n eventName: 'purchase',\n eventSourceUrl: 'https://shop.example.com/checkout/complete',\n customData: {\n value: 249.99,\n currency: 'EUR',\n transactionId: 'ORD-300',\n pageType: 'purchase',\n items: [\n {\n id: 'SKU-A1',\n name: 'Widget Pro',\n price: 124.99,\n quantity: 2,\n },\n ],\n },\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.',\n in: getEvent('page view', {\n timestamp: 1700000901000,\n source: {\n type: 'server',\n id: 'https://example.com/docs/',\n previous_id: '',\n },\n }),\n mapping: {\n settings: { eventType: 'pageLoad' },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'pageLoad',\n eventId: '1700000901000-gr0up-1',\n eventTime: 1700000901,\n adStorageConsent: 'G',\n userData: {},\n eventSourceUrl: 'https://example.com/docs/',\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.',\n in: getEvent('form submit', {\n timestamp: 1700000902000,\n data: { type: 'newsletter' },\n user: { email: 'user@example.com' },\n source: {\n type: 'server',\n id: 'https://example.com/contact',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'lead',\n data: {\n map: {\n userData: {\n map: {\n em: 'user.email',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: '1700000902000-gr0up-1',\n eventTime: 1700000902,\n adStorageConsent: 'G',\n userData: {\n // sha256(normalizeEmail('user@example.com'))\n em: 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514',\n },\n eventName: 'lead',\n eventSourceUrl: 'https://example.com/contact',\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.',\n in: getEvent('product add', {\n timestamp: 1700000903000,\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n color: 'blue',\n },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n quantity: 1,\n },\n },\n ],\n source: {\n type: 'server',\n id: 'https://shop.example.com/products/running-shoes',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'add_to_cart',\n data: {\n map: {\n customData: {\n map: {\n value: 'data.price',\n currency: { value: 'EUR' },\n items: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: '1700000903000-gr0up-1',\n eventTime: 1700000903,\n adStorageConsent: 'G',\n userData: {},\n eventName: 'add_to_cart',\n eventSourceUrl: 'https://shop.example.com/products/running-shoes',\n customData: {\n value: 89.99,\n currency: 'EUR',\n items: [\n {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n quantity: 1,\n },\n ],\n },\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["z","z","z"]}
1
+ {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/schemas/primitives.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 * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Long-lived Bing UET CAPI access token from Microsoft Advertising',\n ),\n tagId: z.string().min(1).describe('Microsoft Advertising UET tag ID'),\n url: z\n .string()\n .url()\n .describe(\n 'Custom Bing UET CAPI base URL (default https://capi.uet.microsoft.com/v1/)',\n )\n .optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"User data fields to skip hashing (like ['em', 'ph'])\")\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\"Mapping for user data fields (like { em: 'user.email' })\")\n .optional(),\n dataProvider: z\n .string()\n .describe('Identifier of the data source (default \"walkerOS\")')\n .optional(),\n continueOnValidationError: z\n .boolean()\n .describe(\n 'When true, Microsoft continues to ingest events despite validation errors',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\nimport { EventTypeSchema } from './primitives';\n\n/**\n * Bing UET CAPI Mapping Schema\n * Per-event overrides. Use `eventType: 'pageLoad'` for page view events.\n */\nexport const MappingSchema = z.object({\n eventType: EventTypeSchema.describe(\n 'Override event type: \"pageLoad\" for page views, \"custom\" (default) otherwise',\n ).optional(),\n});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Bing UET CAPI event type. `pageLoad` for page views, `custom` for all\n * other conversion events.\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nexport const EventTypeSchema = z.enum(['pageLoad', 'custom']);\n\n/**\n * adStorageConsent — `G` when granted, `D` when denied. Defaults to `G`\n * when the event reaches the destination (pre-filtered via consent rules).\n */\nexport const AdStorageConsentSchema = z.enum(['G', 'D']);\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for the Bing UET CAPI destination.\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\nconst mockSendServer: MockSendServer = async () => ({\n ok: true,\n data: {\n status: 'OK',\n requestId: 'mock-123',\n },\n});\n\n/**\n * Standard mock environment for push operations.\n *\n * Use this for testing Bing UET CAPI events without making actual HTTP\n * requests to Microsoft's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Bing UET CAPI step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.tagId}/events`\n * and `body = { data: [capiEvent], dataProvider }`.\n *\n * Test fixture pins `tagId = 'UET-12345'` and the default url, so every\n * endpoint resolves to:\n * https://capi.uet.microsoft.com/v1/UET-12345/events\n *\n * Body is emitted with keys in the order the destination assembles them:\n * 1. eventType\n * 2. eventId\n * 3. eventTime (unix seconds; `Math.round(event.timestamp / 1000)`)\n * 4. adStorageConsent\n * 5. userData (hashed - only `em`, `ph` via SHA-256)\n * 6. eventName (only when eventType === 'custom')\n * 7. eventSourceUrl (only when event.source.url is set)\n * 8. customData (only when it has keys)\n *\n * The `options` argument carries the Authorization + Content-Type headers.\n */\nconst ENDPOINT = 'https://capi.uet.microsoft.com/v1/UET-12345/events';\nconst OPTIONS = {\n headers: {\n Authorization: 'Bearer s3cr3t',\n 'Content-Type': 'application/json',\n },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.',\n in: getEvent('order complete', {\n id: 'b1c2d3e4f5a60001',\n timestamp: 1700000900000,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: { id: 'SKU-A1', name: 'Widget Pro', price: 124.99, quantity: 2 },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/checkout/complete',\n },\n }),\n mapping: {\n name: 'purchase',\n data: {\n map: {\n customData: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n transactionId: 'data.id',\n pageType: { value: 'purchase' },\n items: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n userData: {\n map: {\n externalId: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: 'b1c2d3e4f5a60001',\n eventTime: 1700000900,\n adStorageConsent: 'G',\n userData: {\n externalId: 'user-123',\n },\n eventName: 'purchase',\n eventSourceUrl: 'https://shop.example.com/checkout/complete',\n customData: {\n value: 249.99,\n currency: 'EUR',\n transactionId: 'ORD-300',\n pageType: 'purchase',\n items: [\n {\n id: 'SKU-A1',\n name: 'Widget Pro',\n price: 124.99,\n quantity: 2,\n },\n ],\n },\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.',\n in: getEvent('page view', {\n id: 'b1c2d3e4f5a60002',\n timestamp: 1700000901000,\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/docs/',\n },\n }),\n mapping: {\n settings: { eventType: 'pageLoad' },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'pageLoad',\n eventId: 'b1c2d3e4f5a60002',\n eventTime: 1700000901,\n adStorageConsent: 'G',\n userData: {},\n eventSourceUrl: 'https://example.com/docs/',\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.',\n in: getEvent('form submit', {\n id: 'b1c2d3e4f5a60003',\n timestamp: 1700000902000,\n data: { type: 'newsletter' },\n user: { email: 'user@example.com' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/contact',\n },\n }),\n mapping: {\n name: 'lead',\n data: {\n map: {\n userData: {\n map: {\n em: 'user.email',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: 'b1c2d3e4f5a60003',\n eventTime: 1700000902,\n adStorageConsent: 'G',\n userData: {\n // sha256(normalizeEmail('user@example.com'))\n em: 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514',\n },\n eventName: 'lead',\n eventSourceUrl: 'https://example.com/contact',\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.',\n in: getEvent('product add', {\n id: 'b1c2d3e4f5a60004',\n timestamp: 1700000903000,\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n color: 'blue',\n },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n quantity: 1,\n },\n },\n ],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/products/running-shoes',\n },\n }),\n mapping: {\n name: 'add_to_cart',\n data: {\n map: {\n customData: {\n map: {\n value: 'data.price',\n currency: { value: 'EUR' },\n items: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n eventType: 'custom',\n eventId: 'b1c2d3e4f5a60004',\n eventTime: 1700000903,\n adStorageConsent: 'G',\n userData: {},\n eventName: 'add_to_cart',\n eventSourceUrl: 'https://shop.example.com/products/running-shoes',\n customData: {\n value: 89.99,\n currency: 'EUR',\n items: [\n {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\n quantity: 1,\n },\n ],\n },\n },\n ],\n dataProvider: 'walkerOS',\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["z","z","z"]}
@@ -63,6 +63,7 @@ var purchase = {
63
63
  title: "Purchase",
64
64
  description: "A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.",
65
65
  in: (0, import_core.getEvent)("order complete", {
66
+ id: "b1c2d3e4f5a60001",
66
67
  timestamp: 17000009e5,
67
68
  data: { id: "ORD-300", total: 249.99, currency: "EUR" },
68
69
  nested: [
@@ -73,9 +74,9 @@ var purchase = {
73
74
  ],
74
75
  user: { id: "user-123", device: "device-456" },
75
76
  source: {
76
- type: "server",
77
- id: "https://shop.example.com/checkout/complete",
78
- previous_id: ""
77
+ type: "browser",
78
+ platform: "web",
79
+ url: "https://shop.example.com/checkout/complete"
79
80
  }
80
81
  }),
81
82
  mapping: {
@@ -120,7 +121,7 @@ var purchase = {
120
121
  data: [
121
122
  {
122
123
  eventType: "custom",
123
- eventId: "1700000900000-gr0up-1",
124
+ eventId: "b1c2d3e4f5a60001",
124
125
  eventTime: 1700000900,
125
126
  adStorageConsent: "G",
126
127
  userData: {
@@ -154,11 +155,12 @@ var pageView = {
154
155
  title: "Page view",
155
156
  description: "A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.",
156
157
  in: (0, import_core.getEvent)("page view", {
158
+ id: "b1c2d3e4f5a60002",
157
159
  timestamp: 1700000901e3,
158
160
  source: {
159
- type: "server",
160
- id: "https://example.com/docs/",
161
- previous_id: ""
161
+ type: "browser",
162
+ platform: "web",
163
+ url: "https://example.com/docs/"
162
164
  }
163
165
  }),
164
166
  mapping: {
@@ -172,7 +174,7 @@ var pageView = {
172
174
  data: [
173
175
  {
174
176
  eventType: "pageLoad",
175
- eventId: "1700000901000-gr0up-1",
177
+ eventId: "b1c2d3e4f5a60002",
176
178
  eventTime: 1700000901,
177
179
  adStorageConsent: "G",
178
180
  userData: {},
@@ -189,13 +191,14 @@ var lead = {
189
191
  title: "Lead",
190
192
  description: "A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.",
191
193
  in: (0, import_core.getEvent)("form submit", {
194
+ id: "b1c2d3e4f5a60003",
192
195
  timestamp: 1700000902e3,
193
196
  data: { type: "newsletter" },
194
197
  user: { email: "user@example.com" },
195
198
  source: {
196
- type: "server",
197
- id: "https://example.com/contact",
198
- previous_id: ""
199
+ type: "browser",
200
+ platform: "web",
201
+ url: "https://example.com/contact"
199
202
  }
200
203
  }),
201
204
  mapping: {
@@ -218,7 +221,7 @@ var lead = {
218
221
  data: [
219
222
  {
220
223
  eventType: "custom",
221
- eventId: "1700000902000-gr0up-1",
224
+ eventId: "b1c2d3e4f5a60003",
222
225
  eventTime: 1700000902,
223
226
  adStorageConsent: "G",
224
227
  userData: {
@@ -239,6 +242,7 @@ var addToCart = {
239
242
  title: "Add to cart",
240
243
  description: "A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.",
241
244
  in: (0, import_core.getEvent)("product add", {
245
+ id: "b1c2d3e4f5a60004",
242
246
  timestamp: 1700000903e3,
243
247
  data: {
244
248
  id: "SKU-B2",
@@ -258,9 +262,9 @@ var addToCart = {
258
262
  }
259
263
  ],
260
264
  source: {
261
- type: "server",
262
- id: "https://shop.example.com/products/running-shoes",
263
- previous_id: ""
265
+ type: "browser",
266
+ platform: "web",
267
+ url: "https://shop.example.com/products/running-shoes"
264
268
  }
265
269
  }),
266
270
  mapping: {
@@ -298,7 +302,7 @@ var addToCart = {
298
302
  data: [
299
303
  {
300
304
  eventType: "custom",
301
- eventId: "1700000903000-gr0up-1",
305
+ eventId: "b1c2d3e4f5a60004",
302
306
  eventTime: 1700000903,
303
307
  adStorageConsent: "G",
304
308
  userData: {},
@@ -42,6 +42,7 @@ var purchase = {
42
42
  title: "Purchase",
43
43
  description: "A completed order is sent to the Bing UET CAPI with transaction id, value, items, and hashed user data.",
44
44
  in: getEvent("order complete", {
45
+ id: "b1c2d3e4f5a60001",
45
46
  timestamp: 17000009e5,
46
47
  data: { id: "ORD-300", total: 249.99, currency: "EUR" },
47
48
  nested: [
@@ -52,9 +53,9 @@ var purchase = {
52
53
  ],
53
54
  user: { id: "user-123", device: "device-456" },
54
55
  source: {
55
- type: "server",
56
- id: "https://shop.example.com/checkout/complete",
57
- previous_id: ""
56
+ type: "browser",
57
+ platform: "web",
58
+ url: "https://shop.example.com/checkout/complete"
58
59
  }
59
60
  }),
60
61
  mapping: {
@@ -99,7 +100,7 @@ var purchase = {
99
100
  data: [
100
101
  {
101
102
  eventType: "custom",
102
- eventId: "1700000900000-gr0up-1",
103
+ eventId: "b1c2d3e4f5a60001",
103
104
  eventTime: 1700000900,
104
105
  adStorageConsent: "G",
105
106
  userData: {
@@ -133,11 +134,12 @@ var pageView = {
133
134
  title: "Page view",
134
135
  description: "A page view is sent to the Bing UET CAPI with eventType pageLoad and the source URL.",
135
136
  in: getEvent("page view", {
137
+ id: "b1c2d3e4f5a60002",
136
138
  timestamp: 1700000901e3,
137
139
  source: {
138
- type: "server",
139
- id: "https://example.com/docs/",
140
- previous_id: ""
140
+ type: "browser",
141
+ platform: "web",
142
+ url: "https://example.com/docs/"
141
143
  }
142
144
  }),
143
145
  mapping: {
@@ -151,7 +153,7 @@ var pageView = {
151
153
  data: [
152
154
  {
153
155
  eventType: "pageLoad",
154
- eventId: "1700000901000-gr0up-1",
156
+ eventId: "b1c2d3e4f5a60002",
155
157
  eventTime: 1700000901,
156
158
  adStorageConsent: "G",
157
159
  userData: {},
@@ -168,13 +170,14 @@ var lead = {
168
170
  title: "Lead",
169
171
  description: "A newsletter form submission is sent to Bing UET as a lead event with the SHA-256 hashed email.",
170
172
  in: getEvent("form submit", {
173
+ id: "b1c2d3e4f5a60003",
171
174
  timestamp: 1700000902e3,
172
175
  data: { type: "newsletter" },
173
176
  user: { email: "user@example.com" },
174
177
  source: {
175
- type: "server",
176
- id: "https://example.com/contact",
177
- previous_id: ""
178
+ type: "browser",
179
+ platform: "web",
180
+ url: "https://example.com/contact"
178
181
  }
179
182
  }),
180
183
  mapping: {
@@ -197,7 +200,7 @@ var lead = {
197
200
  data: [
198
201
  {
199
202
  eventType: "custom",
200
- eventId: "1700000902000-gr0up-1",
203
+ eventId: "b1c2d3e4f5a60003",
201
204
  eventTime: 1700000902,
202
205
  adStorageConsent: "G",
203
206
  userData: {
@@ -218,6 +221,7 @@ var addToCart = {
218
221
  title: "Add to cart",
219
222
  description: "A product add is sent to Bing UET as an add_to_cart event with value, currency, and item details.",
220
223
  in: getEvent("product add", {
224
+ id: "b1c2d3e4f5a60004",
221
225
  timestamp: 1700000903e3,
222
226
  data: {
223
227
  id: "SKU-B2",
@@ -237,9 +241,9 @@ var addToCart = {
237
241
  }
238
242
  ],
239
243
  source: {
240
- type: "server",
241
- id: "https://shop.example.com/products/running-shoes",
242
- previous_id: ""
244
+ type: "browser",
245
+ platform: "web",
246
+ url: "https://shop.example.com/products/running-shoes"
243
247
  }
244
248
  }),
245
249
  mapping: {
@@ -277,7 +281,7 @@ var addToCart = {
277
281
  data: [
278
282
  {
279
283
  eventType: "custom",
280
- eventId: "1700000903000-gr0up-1",
284
+ eventId: "b1c2d3e4f5a60004",
281
285
  eventTime: 1700000903,
282
286
  adStorageConsent: "G",
283
287
  userData: {},
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var mod,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,index_exports={};((target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})})(index_exports,{DestinationBing:()=>types_exports,default:()=>index_default,destinationBing:()=>destinationBing}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core=require("@walkeros/core"),import_server_core2=require("@walkeros/server-core"),import_server_core=require("@walkeros/server-core"),keysToHash=["em","ph"];async function hashUserData(userData,doNotHash=[]){const entries=await Promise.all(Object.entries(userData).map(async([key,value])=>{if(void 0===value)return[key,value];if(function(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}(key,doNotHash)){const normalized=function(key,value){return"em"===key?function(value){const trimmed=value.trim().toLowerCase(),atIndex=trimmed.lastIndexOf("@");if(atIndex<0)return trimmed;const user=trimmed.slice(0,atIndex),domain=trimmed.slice(atIndex+1),aliasIndex=user.indexOf("+");return`${(aliasIndex<0?user:user.slice(0,aliasIndex)).replace(/\./g,"")}@${domain}`}(value):"ph"===key?function(value){return value.trim()}(value):value}(key,String(value));return[key,await(0,import_server_core.getHashServer)(normalized)]}return[key,value]}));return Object.fromEntries(entries)}var types_exports={},destinationBing={type:"bing",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,tagId:tagId}=settings;accessToken||logger.throw("Config settings accessToken missing"),tagId||logger.throw("Config settings tagId missing");const settingsConfig={url:"https://capi.uet.microsoft.com/v1/",dataProvider:"walkerOS",...settings,accessToken:accessToken,tagId:tagId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){var _a;const{accessToken:accessToken,tagId:tagId,url:url="https://capi.uet.microsoft.com/v1/",doNotHash:doNotHash,user_data:user_data,dataProvider:dataProvider="walkerOS",continueOnValidationError:continueOnValidationError}=config.settings,eventData=(0,import_core.isObject)(data)?data:{},configData=config.data?await(0,import_core.getMappingValue)(event,config.data):{},userDataCustom=user_data?await(0,import_core.getMappingValue)(event,{map:user_data}):{},ruleSettings=null==rule?void 0:rule.settings,eventType="pageLoad"===(null==ruleSettings?void 0:ruleSettings.eventType)?"pageLoad":"custom",eventMappedUserData=(0,import_core.isObject)(eventData.userData)?eventData.userData:{},userData={...(0,import_core.isObject)(configData)&&(0,import_core.isObject)(configData.userData)?configData.userData:{},...(0,import_core.isObject)(userDataCustom)?userDataCustom:{},...eventMappedUserData},hashedUserData=await hashUserData(userData,doNotHash),customData={};(0,import_core.isObject)(eventData.customData)&&Object.assign(customData,eventData.customData);for(const[key,value]of Object.entries(eventData))"userData"!==key&&"customData"!==key&&(customData[key]=value);const capiEvent={eventType:eventType,eventId:event.id,eventTime:Math.round((event.timestamp||Date.now())/1e3),adStorageConsent:"G",userData:hashedUserData};"custom"===eventType&&(capiEvent.eventName=(null==rule?void 0:rule.name)||event.name),(null==(_a=event.source)?void 0:_a.id)&&(capiEvent.eventSourceUrl=event.source.id),Object.keys(customData).length>0&&(capiEvent.customData=customData);const body={data:[capiEvent],dataProvider:dataProvider};void 0!==continueOnValidationError&&(body.continueOnValidationError=continueOnValidationError);const endpoint=`${url}${tagId}/events`;logger.debug("Calling Bing UET CAPI",{endpoint:endpoint,method:"POST",eventType:capiEvent.eventType,eventName:capiEvent.eventName,eventId:capiEvent.eventId});const sendServerFn=(null==env?void 0:env.sendServer)||import_server_core2.sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`,"Content-Type":"application/json"}});logger.debug("Bing UET CAPI response",{ok:!(0,import_core.isObject)(result)||result.ok}),(0,import_core.isObject)(result)&&!1===result.ok&&logger.throw(`Bing UET CAPI error: ${JSON.stringify(result)}`)}(event,context)},index_default=destinationBing;//# sourceMappingURL=index.js.map
1
+ "use strict";var mod,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,index_exports={};((target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})})(index_exports,{DestinationBing:()=>types_exports,default:()=>index_default,destinationBing:()=>destinationBing}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core=require("@walkeros/core"),import_server_core2=require("@walkeros/server-core"),import_server_core=require("@walkeros/server-core"),keysToHash=["em","ph"];async function hashUserData(userData,doNotHash=[]){const entries=await Promise.all(Object.entries(userData).map(async([key,value])=>{if(void 0===value)return[key,value];if(function(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}(key,doNotHash)){const normalized=function(key,value){return"em"===key?function(value){const trimmed=value.trim().toLowerCase(),atIndex=trimmed.lastIndexOf("@");if(atIndex<0)return trimmed;const user=trimmed.slice(0,atIndex),domain=trimmed.slice(atIndex+1),aliasIndex=user.indexOf("+");return`${(aliasIndex<0?user:user.slice(0,aliasIndex)).replace(/\./g,"")}@${domain}`}(value):"ph"===key?function(value){return value.trim()}(value):value}(key,String(value));return[key,await(0,import_server_core.getHashServer)(normalized)]}return[key,value]}));return Object.fromEntries(entries)}var types_exports={},destinationBing={type:"bing",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,tagId:tagId}=settings;accessToken||logger.throw("Config settings accessToken missing"),tagId||logger.throw("Config settings tagId missing");const settingsConfig={url:"https://capi.uet.microsoft.com/v1/",dataProvider:"walkerOS",...settings,accessToken:accessToken,tagId:tagId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){const{accessToken:accessToken,tagId:tagId,url:url="https://capi.uet.microsoft.com/v1/",doNotHash:doNotHash,user_data:user_data,dataProvider:dataProvider="walkerOS",continueOnValidationError:continueOnValidationError}=config.settings,eventData=(0,import_core.isObject)(data)?data:{},configData=config.data?await(0,import_core.getMappingValue)(event,config.data):{},userDataCustom=user_data?await(0,import_core.getMappingValue)(event,{map:user_data}):{},ruleSettings=rule?.settings,eventType="pageLoad"===ruleSettings?.eventType?"pageLoad":"custom",eventMappedUserData=(0,import_core.isObject)(eventData.userData)?eventData.userData:{},userData={...(0,import_core.isObject)(configData)&&(0,import_core.isObject)(configData.userData)?configData.userData:{},...(0,import_core.isObject)(userDataCustom)?userDataCustom:{},...eventMappedUserData},hashedUserData=await hashUserData(userData,doNotHash),customData={};(0,import_core.isObject)(eventData.customData)&&Object.assign(customData,eventData.customData);for(const[key,value]of Object.entries(eventData))"userData"!==key&&"customData"!==key&&(customData[key]=value);const capiEvent={eventType:eventType,eventId:event.id,eventTime:Math.round((event.timestamp||Date.now())/1e3),adStorageConsent:"G",userData:hashedUserData};"custom"===eventType&&(capiEvent.eventName=rule?.name||event.name),event.source?.url&&(capiEvent.eventSourceUrl=event.source.url),Object.keys(customData).length>0&&(capiEvent.customData=customData);const body={data:[capiEvent],dataProvider:dataProvider};void 0!==continueOnValidationError&&(body.continueOnValidationError=continueOnValidationError);const endpoint=`${url}${tagId}/events`;logger.debug("Calling Bing UET CAPI",{endpoint:endpoint,method:"POST",eventType:capiEvent.eventType,eventName:capiEvent.eventName,eventId:capiEvent.eventId});const sendServerFn=env?.sendServer||import_server_core2.sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`,"Content-Type":"application/json"}});logger.debug("Bing UET CAPI response",{ok:!(0,import_core.isObject)(result)||result.ok}),(0,import_core.isObject)(result)&&!1===result.ok&&logger.throw(`Bing UET CAPI error: ${JSON.stringify(result)}`)}(event,context)},index_default=destinationBing;//# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts"],"sourcesContent":["import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationBing from './types';\n\nexport const destinationBing: Destination = {\n type: 'bing',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationBing;\n","import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, tagId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!tagId) logger.throw('Config settings tagId missing');\n\n const settingsConfig: Settings = {\n url: 'https://capi.uet.microsoft.com/v1/',\n dataProvider: 'walkerOS',\n ...settings,\n accessToken,\n tagId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n CAPIEvent,\n CAPIRequestBody,\n CustomData,\n Env,\n EventType,\n PushFn,\n Settings,\n UserData,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashUserData } from './hash';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n accessToken,\n tagId,\n url = 'https://capi.uet.microsoft.com/v1/',\n doNotHash,\n user_data,\n dataProvider = 'walkerOS',\n continueOnValidationError,\n } = config.settings as Settings;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data)\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Resolve mapping-level eventType override (rule.settings.eventType)\n const ruleSettings = rule?.settings as { eventType?: EventType } | undefined;\n const eventType: EventType =\n ruleSettings?.eventType === 'pageLoad' ? 'pageLoad' : 'custom';\n\n // Build user_data from merge sources (priority: later overrides earlier)\n const eventMappedUserData = isObject(eventData.userData)\n ? (eventData.userData as UserData)\n : {};\n\n const userData: UserData = {\n ...(isObject(configData) && isObject(configData.userData)\n ? (configData.userData as UserData)\n : {}),\n ...(isObject(userDataCustom) ? (userDataCustom as UserData) : {}),\n ...eventMappedUserData,\n };\n\n // Hash identity fields (em, ph only; with Microsoft email normalization)\n const hashedUserData = await hashUserData(userData, doNotHash);\n\n // Build customData from mapped event data\n const customData: CustomData = {};\n if (isObject(eventData.customData)) {\n Object.assign(customData, eventData.customData);\n }\n for (const [key, value] of Object.entries(eventData)) {\n if (key === 'userData' || key === 'customData') continue;\n customData[key] = value;\n }\n\n // Build Bing CAPI event\n const capiEvent: CAPIEvent = {\n eventType,\n eventId: event.id,\n eventTime: Math.round((event.timestamp || Date.now()) / 1000),\n adStorageConsent: 'G',\n userData: hashedUserData,\n };\n\n if (eventType === 'custom') {\n capiEvent.eventName = rule?.name || event.name;\n }\n\n if (event.source?.id) {\n capiEvent.eventSourceUrl = event.source.id;\n }\n\n if (Object.keys(customData).length > 0) {\n capiEvent.customData = customData;\n }\n\n const body: CAPIRequestBody = {\n data: [capiEvent],\n dataProvider,\n };\n\n if (continueOnValidationError !== undefined) {\n body.continueOnValidationError = continueOnValidationError;\n }\n\n const endpoint = `${url}${tagId}/events`;\n\n logger.debug('Calling Bing UET CAPI', {\n endpoint,\n method: 'POST',\n eventType: capiEvent.eventType,\n eventName: capiEvent.eventName,\n eventId: capiEvent.eventId,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n });\n\n logger.debug('Bing UET CAPI response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Bing UET CAPI error: ${JSON.stringify(result)}`);\n }\n};\n","import type { UserData } from './types';\nimport { getHashServer } from '@walkeros/server-core';\n\n/**\n * Bing UET CAPI user data fields that must be SHA-256 hashed before sending.\n * Only `em` and `ph` are hashable; all other identity fields pass through\n * unhashed (anonymousId, externalId, msclkid, clientIpAddress,\n * clientUserAgent, idfa, gaid).\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nconst keysToHash = ['em', 'ph'];\n\n/**\n * Microsoft-specific email normalization:\n * - Trim whitespace\n * - Lowercase\n * - Split at `@`\n * - Remove dots from the user portion\n * - Strip `+alias` suffix from the user portion\n * - Rejoin\n */\nexport function normalizeEmail(value: string): string {\n const trimmed = value.trim().toLowerCase();\n const atIndex = trimmed.lastIndexOf('@');\n if (atIndex < 0) return trimmed;\n\n const user = trimmed.slice(0, atIndex);\n const domain = trimmed.slice(atIndex + 1);\n\n const aliasIndex = user.indexOf('+');\n const beforeAlias = aliasIndex < 0 ? user : user.slice(0, aliasIndex);\n const normalizedUser = beforeAlias.replace(/\\./g, '');\n\n return `${normalizedUser}@${domain}`;\n}\n\nfunction normalizePhone(value: string): string {\n return value.trim();\n}\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\nfunction normalizeForKey(key: string, value: string): string {\n if (key === 'em') return normalizeEmail(value);\n if (key === 'ph') return normalizePhone(value);\n return value;\n}\n\nexport async function hashUserData(\n userData: UserData,\n doNotHash: string[] = [],\n): Promise<UserData> {\n const entries = await Promise.all(\n Object.entries(userData).map(async ([key, value]) => {\n if (value === undefined) return [key, value];\n if (shouldBeHashed(key, doNotHash)) {\n const normalized = normalizeForKey(key, String(value));\n return [key, await getHashServer(normalized)];\n }\n return [key, value];\n }),\n );\n\n return Object.fromEntries(entries) as UserData;\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n tagId: string;\n url?: string;\n doNotHash?: string[];\n user_data?: WalkerOSMapping.Map;\n dataProvider?: string;\n continueOnValidationError?: boolean;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n eventType?: EventType;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n/**\n * Microsoft Advertising (Bing) UET Conversions API\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nexport type EventType = 'pageLoad' | 'custom';\n\nexport type AdStorageConsent = 'G' | 'D';\n\nexport interface CAPIRequestBody {\n data: CAPIEvent[];\n dataProvider?: string;\n continueOnValidationError?: boolean;\n}\n\nexport interface CAPIEvent {\n eventType: EventType;\n eventId?: string;\n eventName?: string;\n eventTime: number;\n eventSourceUrl?: string;\n pageLoadId?: string;\n referrerUrl?: string;\n pageTitle?: string;\n keywords?: string;\n adStorageConsent?: AdStorageConsent;\n userData?: UserData;\n customData?: CustomData;\n}\n\n// User identity fields. Hashable: em, ph. Non-hashable: anonymousId,\n// externalId, msclkid, clientIpAddress, clientUserAgent, idfa, gaid.\nexport interface UserData {\n /** Anonymous ID. Do NOT hash. */\n anonymousId?: string;\n /** External/customer ID. Do NOT hash. */\n externalId?: string;\n /** Email, SHA-256 hashed, normalized (dots/alias stripped, lowercased) */\n em?: string;\n /** Phone number, SHA-256 hashed, trimmed */\n ph?: string;\n /** Microsoft click ID. Do NOT hash. */\n msclkid?: string;\n /** Client IP address (IPv4 or IPv6). Do NOT hash. */\n clientIpAddress?: string;\n /** Client user agent. Do NOT hash. */\n clientUserAgent?: string;\n /** iOS IDFA. Do NOT hash. */\n idfa?: string;\n /** Android advertising ID (GAID). Do NOT hash. */\n gaid?: string;\n}\n\nexport interface CustomData {\n eventCategory?: string;\n eventLabel?: string;\n eventValue?: number;\n searchTerm?: string;\n transactionId?: string;\n value?: number;\n currency?: string;\n items?: ItemData[];\n itemIds?: string[];\n pageType?: string;\n ecommTotalValue?: number;\n ecommCategory?: string;\n hotelData?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface ItemData {\n id?: string;\n quantity?: number;\n price?: number;\n name?: string;\n}\n\nexport interface ResponseBody {\n status?: string;\n requestId?: string;\n}\n"],"mappings":"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","names":["import_server_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts"],"sourcesContent":["import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationBing from './types';\n\nexport const destinationBing: Destination = {\n type: 'bing',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationBing;\n","import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, tagId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!tagId) logger.throw('Config settings tagId missing');\n\n const settingsConfig: Settings = {\n url: 'https://capi.uet.microsoft.com/v1/',\n dataProvider: 'walkerOS',\n ...settings,\n accessToken,\n tagId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n CAPIEvent,\n CAPIRequestBody,\n CustomData,\n Env,\n EventType,\n PushFn,\n Settings,\n UserData,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashUserData } from './hash';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n accessToken,\n tagId,\n url = 'https://capi.uet.microsoft.com/v1/',\n doNotHash,\n user_data,\n dataProvider = 'walkerOS',\n continueOnValidationError,\n } = config.settings as Settings;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data)\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Resolve mapping-level eventType override (rule.settings.eventType)\n const ruleSettings = rule?.settings as { eventType?: EventType } | undefined;\n const eventType: EventType =\n ruleSettings?.eventType === 'pageLoad' ? 'pageLoad' : 'custom';\n\n // Build user_data from merge sources (priority: later overrides earlier)\n const eventMappedUserData = isObject(eventData.userData)\n ? (eventData.userData as UserData)\n : {};\n\n const userData: UserData = {\n ...(isObject(configData) && isObject(configData.userData)\n ? (configData.userData as UserData)\n : {}),\n ...(isObject(userDataCustom) ? (userDataCustom as UserData) : {}),\n ...eventMappedUserData,\n };\n\n // Hash identity fields (em, ph only; with Microsoft email normalization)\n const hashedUserData = await hashUserData(userData, doNotHash);\n\n // Build customData from mapped event data\n const customData: CustomData = {};\n if (isObject(eventData.customData)) {\n Object.assign(customData, eventData.customData);\n }\n for (const [key, value] of Object.entries(eventData)) {\n if (key === 'userData' || key === 'customData') continue;\n customData[key] = value;\n }\n\n // Build Bing CAPI event\n const capiEvent: CAPIEvent = {\n eventType,\n eventId: event.id,\n eventTime: Math.round((event.timestamp || Date.now()) / 1000),\n adStorageConsent: 'G',\n userData: hashedUserData,\n };\n\n if (eventType === 'custom') {\n capiEvent.eventName = rule?.name || event.name;\n }\n\n if (event.source?.url) {\n capiEvent.eventSourceUrl = event.source.url;\n }\n\n if (Object.keys(customData).length > 0) {\n capiEvent.customData = customData;\n }\n\n const body: CAPIRequestBody = {\n data: [capiEvent],\n dataProvider,\n };\n\n if (continueOnValidationError !== undefined) {\n body.continueOnValidationError = continueOnValidationError;\n }\n\n const endpoint = `${url}${tagId}/events`;\n\n logger.debug('Calling Bing UET CAPI', {\n endpoint,\n method: 'POST',\n eventType: capiEvent.eventType,\n eventName: capiEvent.eventName,\n eventId: capiEvent.eventId,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n });\n\n logger.debug('Bing UET CAPI response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Bing UET CAPI error: ${JSON.stringify(result)}`);\n }\n};\n","import type { UserData } from './types';\nimport { getHashServer } from '@walkeros/server-core';\n\n/**\n * Bing UET CAPI user data fields that must be SHA-256 hashed before sending.\n * Only `em` and `ph` are hashable; all other identity fields pass through\n * unhashed (anonymousId, externalId, msclkid, clientIpAddress,\n * clientUserAgent, idfa, gaid).\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nconst keysToHash = ['em', 'ph'];\n\n/**\n * Microsoft-specific email normalization:\n * - Trim whitespace\n * - Lowercase\n * - Split at `@`\n * - Remove dots from the user portion\n * - Strip `+alias` suffix from the user portion\n * - Rejoin\n */\nexport function normalizeEmail(value: string): string {\n const trimmed = value.trim().toLowerCase();\n const atIndex = trimmed.lastIndexOf('@');\n if (atIndex < 0) return trimmed;\n\n const user = trimmed.slice(0, atIndex);\n const domain = trimmed.slice(atIndex + 1);\n\n const aliasIndex = user.indexOf('+');\n const beforeAlias = aliasIndex < 0 ? user : user.slice(0, aliasIndex);\n const normalizedUser = beforeAlias.replace(/\\./g, '');\n\n return `${normalizedUser}@${domain}`;\n}\n\nfunction normalizePhone(value: string): string {\n return value.trim();\n}\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\nfunction normalizeForKey(key: string, value: string): string {\n if (key === 'em') return normalizeEmail(value);\n if (key === 'ph') return normalizePhone(value);\n return value;\n}\n\nexport async function hashUserData(\n userData: UserData,\n doNotHash: string[] = [],\n): Promise<UserData> {\n const entries = await Promise.all(\n Object.entries(userData).map(async ([key, value]) => {\n if (value === undefined) return [key, value];\n if (shouldBeHashed(key, doNotHash)) {\n const normalized = normalizeForKey(key, String(value));\n return [key, await getHashServer(normalized)];\n }\n return [key, value];\n }),\n );\n\n return Object.fromEntries(entries) as UserData;\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n tagId: string;\n url?: string;\n doNotHash?: string[];\n user_data?: WalkerOSMapping.Map;\n dataProvider?: string;\n continueOnValidationError?: boolean;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n eventType?: EventType;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n/**\n * Microsoft Advertising (Bing) UET Conversions API\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nexport type EventType = 'pageLoad' | 'custom';\n\nexport type AdStorageConsent = 'G' | 'D';\n\nexport interface CAPIRequestBody {\n data: CAPIEvent[];\n dataProvider?: string;\n continueOnValidationError?: boolean;\n}\n\nexport interface CAPIEvent {\n eventType: EventType;\n eventId?: string;\n eventName?: string;\n eventTime: number;\n eventSourceUrl?: string;\n pageLoadId?: string;\n referrerUrl?: string;\n pageTitle?: string;\n keywords?: string;\n adStorageConsent?: AdStorageConsent;\n userData?: UserData;\n customData?: CustomData;\n}\n\n// User identity fields. Hashable: em, ph. Non-hashable: anonymousId,\n// externalId, msclkid, clientIpAddress, clientUserAgent, idfa, gaid.\nexport interface UserData {\n /** Anonymous ID. Do NOT hash. */\n anonymousId?: string;\n /** External/customer ID. Do NOT hash. */\n externalId?: string;\n /** Email, SHA-256 hashed, normalized (dots/alias stripped, lowercased) */\n em?: string;\n /** Phone number, SHA-256 hashed, trimmed */\n ph?: string;\n /** Microsoft click ID. Do NOT hash. */\n msclkid?: string;\n /** Client IP address (IPv4 or IPv6). Do NOT hash. */\n clientIpAddress?: string;\n /** Client user agent. Do NOT hash. */\n clientUserAgent?: string;\n /** iOS IDFA. Do NOT hash. */\n idfa?: string;\n /** Android advertising ID (GAID). Do NOT hash. */\n gaid?: string;\n}\n\nexport interface CustomData {\n eventCategory?: string;\n eventLabel?: string;\n eventValue?: number;\n searchTerm?: string;\n transactionId?: string;\n value?: number;\n currency?: string;\n items?: ItemData[];\n itemIds?: string[];\n pageType?: string;\n ecommTotalValue?: number;\n ecommCategory?: string;\n hotelData?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface ItemData {\n id?: string;\n quantity?: number;\n price?: number;\n name?: string;\n}\n\nexport interface ResponseBody {\n status?: string;\n requestId?: string;\n}\n"],"mappings":"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","names":["import_server_core"]}
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{getMappingValue,isObject}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{getHashServer}from"@walkeros/server-core";var keysToHash=["em","ph"];async function hashUserData(userData,doNotHash=[]){const entries=await Promise.all(Object.entries(userData).map(async([key,value])=>{if(void 0===value)return[key,value];if(function(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}(key,doNotHash)){const normalized=function(key,value){return"em"===key?function(value){const trimmed=value.trim().toLowerCase(),atIndex=trimmed.lastIndexOf("@");if(atIndex<0)return trimmed;const user=trimmed.slice(0,atIndex),domain=trimmed.slice(atIndex+1),aliasIndex=user.indexOf("+");return`${(aliasIndex<0?user:user.slice(0,aliasIndex)).replace(/\./g,"")}@${domain}`}(value):"ph"===key?function(value){return value.trim()}(value):value}(key,String(value));return[key,await getHashServer(normalized)]}return[key,value]}));return Object.fromEntries(entries)}var types_exports={},destinationBing={type:"bing",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,tagId:tagId}=settings;accessToken||logger.throw("Config settings accessToken missing"),tagId||logger.throw("Config settings tagId missing");const settingsConfig={url:"https://capi.uet.microsoft.com/v1/",dataProvider:"walkerOS",...settings,accessToken:accessToken,tagId:tagId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){var _a;const{accessToken:accessToken,tagId:tagId,url:url="https://capi.uet.microsoft.com/v1/",doNotHash:doNotHash,user_data:user_data,dataProvider:dataProvider="walkerOS",continueOnValidationError:continueOnValidationError}=config.settings,eventData=isObject(data)?data:{},configData=config.data?await getMappingValue(event,config.data):{},userDataCustom=user_data?await getMappingValue(event,{map:user_data}):{},ruleSettings=null==rule?void 0:rule.settings,eventType="pageLoad"===(null==ruleSettings?void 0:ruleSettings.eventType)?"pageLoad":"custom",eventMappedUserData=isObject(eventData.userData)?eventData.userData:{},userData={...isObject(configData)&&isObject(configData.userData)?configData.userData:{},...isObject(userDataCustom)?userDataCustom:{},...eventMappedUserData},hashedUserData=await hashUserData(userData,doNotHash),customData={};isObject(eventData.customData)&&Object.assign(customData,eventData.customData);for(const[key,value]of Object.entries(eventData))"userData"!==key&&"customData"!==key&&(customData[key]=value);const capiEvent={eventType:eventType,eventId:event.id,eventTime:Math.round((event.timestamp||Date.now())/1e3),adStorageConsent:"G",userData:hashedUserData};"custom"===eventType&&(capiEvent.eventName=(null==rule?void 0:rule.name)||event.name),(null==(_a=event.source)?void 0:_a.id)&&(capiEvent.eventSourceUrl=event.source.id),Object.keys(customData).length>0&&(capiEvent.customData=customData);const body={data:[capiEvent],dataProvider:dataProvider};void 0!==continueOnValidationError&&(body.continueOnValidationError=continueOnValidationError);const endpoint=`${url}${tagId}/events`;logger.debug("Calling Bing UET CAPI",{endpoint:endpoint,method:"POST",eventType:capiEvent.eventType,eventName:capiEvent.eventName,eventId:capiEvent.eventId});const sendServerFn=(null==env?void 0:env.sendServer)||sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`,"Content-Type":"application/json"}});logger.debug("Bing UET CAPI response",{ok:!isObject(result)||result.ok}),isObject(result)&&!1===result.ok&&logger.throw(`Bing UET CAPI error: ${JSON.stringify(result)}`)}(event,context)},index_default=destinationBing;export{types_exports as DestinationBing,index_default as default,destinationBing};//# sourceMappingURL=index.mjs.map
1
+ import{getMappingValue,isObject}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{getHashServer}from"@walkeros/server-core";var keysToHash=["em","ph"];async function hashUserData(userData,doNotHash=[]){const entries=await Promise.all(Object.entries(userData).map(async([key,value])=>{if(void 0===value)return[key,value];if(function(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}(key,doNotHash)){const normalized=function(key,value){return"em"===key?function(value){const trimmed=value.trim().toLowerCase(),atIndex=trimmed.lastIndexOf("@");if(atIndex<0)return trimmed;const user=trimmed.slice(0,atIndex),domain=trimmed.slice(atIndex+1),aliasIndex=user.indexOf("+");return`${(aliasIndex<0?user:user.slice(0,aliasIndex)).replace(/\./g,"")}@${domain}`}(value):"ph"===key?function(value){return value.trim()}(value):value}(key,String(value));return[key,await getHashServer(normalized)]}return[key,value]}));return Object.fromEntries(entries)}var types_exports={},destinationBing={type:"bing",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,tagId:tagId}=settings;accessToken||logger.throw("Config settings accessToken missing"),tagId||logger.throw("Config settings tagId missing");const settingsConfig={url:"https://capi.uet.microsoft.com/v1/",dataProvider:"walkerOS",...settings,accessToken:accessToken,tagId:tagId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){const{accessToken:accessToken,tagId:tagId,url:url="https://capi.uet.microsoft.com/v1/",doNotHash:doNotHash,user_data:user_data,dataProvider:dataProvider="walkerOS",continueOnValidationError:continueOnValidationError}=config.settings,eventData=isObject(data)?data:{},configData=config.data?await getMappingValue(event,config.data):{},userDataCustom=user_data?await getMappingValue(event,{map:user_data}):{},ruleSettings=rule?.settings,eventType="pageLoad"===ruleSettings?.eventType?"pageLoad":"custom",eventMappedUserData=isObject(eventData.userData)?eventData.userData:{},userData={...isObject(configData)&&isObject(configData.userData)?configData.userData:{},...isObject(userDataCustom)?userDataCustom:{},...eventMappedUserData},hashedUserData=await hashUserData(userData,doNotHash),customData={};isObject(eventData.customData)&&Object.assign(customData,eventData.customData);for(const[key,value]of Object.entries(eventData))"userData"!==key&&"customData"!==key&&(customData[key]=value);const capiEvent={eventType:eventType,eventId:event.id,eventTime:Math.round((event.timestamp||Date.now())/1e3),adStorageConsent:"G",userData:hashedUserData};"custom"===eventType&&(capiEvent.eventName=rule?.name||event.name),event.source?.url&&(capiEvent.eventSourceUrl=event.source.url),Object.keys(customData).length>0&&(capiEvent.customData=customData);const body={data:[capiEvent],dataProvider:dataProvider};void 0!==continueOnValidationError&&(body.continueOnValidationError=continueOnValidationError);const endpoint=`${url}${tagId}/events`;logger.debug("Calling Bing UET CAPI",{endpoint:endpoint,method:"POST",eventType:capiEvent.eventType,eventName:capiEvent.eventName,eventId:capiEvent.eventId});const sendServerFn=env?.sendServer||sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`,"Content-Type":"application/json"}});logger.debug("Bing UET CAPI response",{ok:!isObject(result)||result.ok}),isObject(result)&&!1===result.ok&&logger.throw(`Bing UET CAPI error: ${JSON.stringify(result)}`)}(event,context)},index_default=destinationBing;export{types_exports as DestinationBing,index_default as default,destinationBing};//# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, tagId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!tagId) logger.throw('Config settings tagId missing');\n\n const settingsConfig: Settings = {\n url: 'https://capi.uet.microsoft.com/v1/',\n dataProvider: 'walkerOS',\n ...settings,\n accessToken,\n tagId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n CAPIEvent,\n CAPIRequestBody,\n CustomData,\n Env,\n EventType,\n PushFn,\n Settings,\n UserData,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashUserData } from './hash';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n accessToken,\n tagId,\n url = 'https://capi.uet.microsoft.com/v1/',\n doNotHash,\n user_data,\n dataProvider = 'walkerOS',\n continueOnValidationError,\n } = config.settings as Settings;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data)\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Resolve mapping-level eventType override (rule.settings.eventType)\n const ruleSettings = rule?.settings as { eventType?: EventType } | undefined;\n const eventType: EventType =\n ruleSettings?.eventType === 'pageLoad' ? 'pageLoad' : 'custom';\n\n // Build user_data from merge sources (priority: later overrides earlier)\n const eventMappedUserData = isObject(eventData.userData)\n ? (eventData.userData as UserData)\n : {};\n\n const userData: UserData = {\n ...(isObject(configData) && isObject(configData.userData)\n ? (configData.userData as UserData)\n : {}),\n ...(isObject(userDataCustom) ? (userDataCustom as UserData) : {}),\n ...eventMappedUserData,\n };\n\n // Hash identity fields (em, ph only; with Microsoft email normalization)\n const hashedUserData = await hashUserData(userData, doNotHash);\n\n // Build customData from mapped event data\n const customData: CustomData = {};\n if (isObject(eventData.customData)) {\n Object.assign(customData, eventData.customData);\n }\n for (const [key, value] of Object.entries(eventData)) {\n if (key === 'userData' || key === 'customData') continue;\n customData[key] = value;\n }\n\n // Build Bing CAPI event\n const capiEvent: CAPIEvent = {\n eventType,\n eventId: event.id,\n eventTime: Math.round((event.timestamp || Date.now()) / 1000),\n adStorageConsent: 'G',\n userData: hashedUserData,\n };\n\n if (eventType === 'custom') {\n capiEvent.eventName = rule?.name || event.name;\n }\n\n if (event.source?.id) {\n capiEvent.eventSourceUrl = event.source.id;\n }\n\n if (Object.keys(customData).length > 0) {\n capiEvent.customData = customData;\n }\n\n const body: CAPIRequestBody = {\n data: [capiEvent],\n dataProvider,\n };\n\n if (continueOnValidationError !== undefined) {\n body.continueOnValidationError = continueOnValidationError;\n }\n\n const endpoint = `${url}${tagId}/events`;\n\n logger.debug('Calling Bing UET CAPI', {\n endpoint,\n method: 'POST',\n eventType: capiEvent.eventType,\n eventName: capiEvent.eventName,\n eventId: capiEvent.eventId,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n });\n\n logger.debug('Bing UET CAPI response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Bing UET CAPI error: ${JSON.stringify(result)}`);\n }\n};\n","import type { UserData } from './types';\nimport { getHashServer } from '@walkeros/server-core';\n\n/**\n * Bing UET CAPI user data fields that must be SHA-256 hashed before sending.\n * Only `em` and `ph` are hashable; all other identity fields pass through\n * unhashed (anonymousId, externalId, msclkid, clientIpAddress,\n * clientUserAgent, idfa, gaid).\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nconst keysToHash = ['em', 'ph'];\n\n/**\n * Microsoft-specific email normalization:\n * - Trim whitespace\n * - Lowercase\n * - Split at `@`\n * - Remove dots from the user portion\n * - Strip `+alias` suffix from the user portion\n * - Rejoin\n */\nexport function normalizeEmail(value: string): string {\n const trimmed = value.trim().toLowerCase();\n const atIndex = trimmed.lastIndexOf('@');\n if (atIndex < 0) return trimmed;\n\n const user = trimmed.slice(0, atIndex);\n const domain = trimmed.slice(atIndex + 1);\n\n const aliasIndex = user.indexOf('+');\n const beforeAlias = aliasIndex < 0 ? user : user.slice(0, aliasIndex);\n const normalizedUser = beforeAlias.replace(/\\./g, '');\n\n return `${normalizedUser}@${domain}`;\n}\n\nfunction normalizePhone(value: string): string {\n return value.trim();\n}\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\nfunction normalizeForKey(key: string, value: string): string {\n if (key === 'em') return normalizeEmail(value);\n if (key === 'ph') return normalizePhone(value);\n return value;\n}\n\nexport async function hashUserData(\n userData: UserData,\n doNotHash: string[] = [],\n): Promise<UserData> {\n const entries = await Promise.all(\n Object.entries(userData).map(async ([key, value]) => {\n if (value === undefined) return [key, value];\n if (shouldBeHashed(key, doNotHash)) {\n const normalized = normalizeForKey(key, String(value));\n return [key, await getHashServer(normalized)];\n }\n return [key, value];\n }),\n );\n\n return Object.fromEntries(entries) as UserData;\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n tagId: string;\n url?: string;\n doNotHash?: string[];\n user_data?: WalkerOSMapping.Map;\n dataProvider?: string;\n continueOnValidationError?: boolean;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n eventType?: EventType;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n/**\n * Microsoft Advertising (Bing) UET Conversions API\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nexport type EventType = 'pageLoad' | 'custom';\n\nexport type AdStorageConsent = 'G' | 'D';\n\nexport interface CAPIRequestBody {\n data: CAPIEvent[];\n dataProvider?: string;\n continueOnValidationError?: boolean;\n}\n\nexport interface CAPIEvent {\n eventType: EventType;\n eventId?: string;\n eventName?: string;\n eventTime: number;\n eventSourceUrl?: string;\n pageLoadId?: string;\n referrerUrl?: string;\n pageTitle?: string;\n keywords?: string;\n adStorageConsent?: AdStorageConsent;\n userData?: UserData;\n customData?: CustomData;\n}\n\n// User identity fields. Hashable: em, ph. Non-hashable: anonymousId,\n// externalId, msclkid, clientIpAddress, clientUserAgent, idfa, gaid.\nexport interface UserData {\n /** Anonymous ID. Do NOT hash. */\n anonymousId?: string;\n /** External/customer ID. Do NOT hash. */\n externalId?: string;\n /** Email, SHA-256 hashed, normalized (dots/alias stripped, lowercased) */\n em?: string;\n /** Phone number, SHA-256 hashed, trimmed */\n ph?: string;\n /** Microsoft click ID. Do NOT hash. */\n msclkid?: string;\n /** Client IP address (IPv4 or IPv6). Do NOT hash. */\n clientIpAddress?: string;\n /** Client user agent. Do NOT hash. */\n clientUserAgent?: string;\n /** iOS IDFA. Do NOT hash. */\n idfa?: string;\n /** Android advertising ID (GAID). Do NOT hash. */\n gaid?: string;\n}\n\nexport interface CustomData {\n eventCategory?: string;\n eventLabel?: string;\n eventValue?: number;\n searchTerm?: string;\n transactionId?: string;\n value?: number;\n currency?: string;\n items?: ItemData[];\n itemIds?: string[];\n pageType?: string;\n ecommTotalValue?: number;\n ecommCategory?: string;\n hotelData?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface ItemData {\n id?: string;\n quantity?: number;\n price?: number;\n name?: string;\n}\n\nexport interface ResponseBody {\n status?: string;\n requestId?: string;\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationBing from './types';\n\nexport const destinationBing: Destination = {\n type: 'bing',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationBing;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, tagId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!tagId) logger.throw('Config settings tagId missing');\n\n const settingsConfig: Settings = {\n url: 'https://capi.uet.microsoft.com/v1/',\n dataProvider: 'walkerOS',\n ...settings,\n accessToken,\n tagId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n CAPIEvent,\n CAPIRequestBody,\n CustomData,\n Env,\n EventType,\n PushFn,\n Settings,\n UserData,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashUserData } from './hash';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n accessToken,\n tagId,\n url = 'https://capi.uet.microsoft.com/v1/',\n doNotHash,\n user_data,\n dataProvider = 'walkerOS',\n continueOnValidationError,\n } = config.settings as Settings;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data)\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Resolve mapping-level eventType override (rule.settings.eventType)\n const ruleSettings = rule?.settings as { eventType?: EventType } | undefined;\n const eventType: EventType =\n ruleSettings?.eventType === 'pageLoad' ? 'pageLoad' : 'custom';\n\n // Build user_data from merge sources (priority: later overrides earlier)\n const eventMappedUserData = isObject(eventData.userData)\n ? (eventData.userData as UserData)\n : {};\n\n const userData: UserData = {\n ...(isObject(configData) && isObject(configData.userData)\n ? (configData.userData as UserData)\n : {}),\n ...(isObject(userDataCustom) ? (userDataCustom as UserData) : {}),\n ...eventMappedUserData,\n };\n\n // Hash identity fields (em, ph only; with Microsoft email normalization)\n const hashedUserData = await hashUserData(userData, doNotHash);\n\n // Build customData from mapped event data\n const customData: CustomData = {};\n if (isObject(eventData.customData)) {\n Object.assign(customData, eventData.customData);\n }\n for (const [key, value] of Object.entries(eventData)) {\n if (key === 'userData' || key === 'customData') continue;\n customData[key] = value;\n }\n\n // Build Bing CAPI event\n const capiEvent: CAPIEvent = {\n eventType,\n eventId: event.id,\n eventTime: Math.round((event.timestamp || Date.now()) / 1000),\n adStorageConsent: 'G',\n userData: hashedUserData,\n };\n\n if (eventType === 'custom') {\n capiEvent.eventName = rule?.name || event.name;\n }\n\n if (event.source?.url) {\n capiEvent.eventSourceUrl = event.source.url;\n }\n\n if (Object.keys(customData).length > 0) {\n capiEvent.customData = customData;\n }\n\n const body: CAPIRequestBody = {\n data: [capiEvent],\n dataProvider,\n };\n\n if (continueOnValidationError !== undefined) {\n body.continueOnValidationError = continueOnValidationError;\n }\n\n const endpoint = `${url}${tagId}/events`;\n\n logger.debug('Calling Bing UET CAPI', {\n endpoint,\n method: 'POST',\n eventType: capiEvent.eventType,\n eventName: capiEvent.eventName,\n eventId: capiEvent.eventId,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n });\n\n logger.debug('Bing UET CAPI response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Bing UET CAPI error: ${JSON.stringify(result)}`);\n }\n};\n","import type { UserData } from './types';\nimport { getHashServer } from '@walkeros/server-core';\n\n/**\n * Bing UET CAPI user data fields that must be SHA-256 hashed before sending.\n * Only `em` and `ph` are hashable; all other identity fields pass through\n * unhashed (anonymousId, externalId, msclkid, clientIpAddress,\n * clientUserAgent, idfa, gaid).\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nconst keysToHash = ['em', 'ph'];\n\n/**\n * Microsoft-specific email normalization:\n * - Trim whitespace\n * - Lowercase\n * - Split at `@`\n * - Remove dots from the user portion\n * - Strip `+alias` suffix from the user portion\n * - Rejoin\n */\nexport function normalizeEmail(value: string): string {\n const trimmed = value.trim().toLowerCase();\n const atIndex = trimmed.lastIndexOf('@');\n if (atIndex < 0) return trimmed;\n\n const user = trimmed.slice(0, atIndex);\n const domain = trimmed.slice(atIndex + 1);\n\n const aliasIndex = user.indexOf('+');\n const beforeAlias = aliasIndex < 0 ? user : user.slice(0, aliasIndex);\n const normalizedUser = beforeAlias.replace(/\\./g, '');\n\n return `${normalizedUser}@${domain}`;\n}\n\nfunction normalizePhone(value: string): string {\n return value.trim();\n}\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\nfunction normalizeForKey(key: string, value: string): string {\n if (key === 'em') return normalizeEmail(value);\n if (key === 'ph') return normalizePhone(value);\n return value;\n}\n\nexport async function hashUserData(\n userData: UserData,\n doNotHash: string[] = [],\n): Promise<UserData> {\n const entries = await Promise.all(\n Object.entries(userData).map(async ([key, value]) => {\n if (value === undefined) return [key, value];\n if (shouldBeHashed(key, doNotHash)) {\n const normalized = normalizeForKey(key, String(value));\n return [key, await getHashServer(normalized)];\n }\n return [key, value];\n }),\n );\n\n return Object.fromEntries(entries) as UserData;\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n tagId: string;\n url?: string;\n doNotHash?: string[];\n user_data?: WalkerOSMapping.Map;\n dataProvider?: string;\n continueOnValidationError?: boolean;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n eventType?: EventType;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n/**\n * Microsoft Advertising (Bing) UET Conversions API\n * https://learn.microsoft.com/en-us/advertising/guides/universal-event-tracking-capi\n */\nexport type EventType = 'pageLoad' | 'custom';\n\nexport type AdStorageConsent = 'G' | 'D';\n\nexport interface CAPIRequestBody {\n data: CAPIEvent[];\n dataProvider?: string;\n continueOnValidationError?: boolean;\n}\n\nexport interface CAPIEvent {\n eventType: EventType;\n eventId?: string;\n eventName?: string;\n eventTime: number;\n eventSourceUrl?: string;\n pageLoadId?: string;\n referrerUrl?: string;\n pageTitle?: string;\n keywords?: string;\n adStorageConsent?: AdStorageConsent;\n userData?: UserData;\n customData?: CustomData;\n}\n\n// User identity fields. Hashable: em, ph. Non-hashable: anonymousId,\n// externalId, msclkid, clientIpAddress, clientUserAgent, idfa, gaid.\nexport interface UserData {\n /** Anonymous ID. Do NOT hash. */\n anonymousId?: string;\n /** External/customer ID. Do NOT hash. */\n externalId?: string;\n /** Email, SHA-256 hashed, normalized (dots/alias stripped, lowercased) */\n em?: string;\n /** Phone number, SHA-256 hashed, trimmed */\n ph?: string;\n /** Microsoft click ID. Do NOT hash. */\n msclkid?: string;\n /** Client IP address (IPv4 or IPv6). Do NOT hash. */\n clientIpAddress?: string;\n /** Client user agent. Do NOT hash. */\n clientUserAgent?: string;\n /** iOS IDFA. Do NOT hash. */\n idfa?: string;\n /** Android advertising ID (GAID). Do NOT hash. */\n gaid?: string;\n}\n\nexport interface CustomData {\n eventCategory?: string;\n eventLabel?: string;\n eventValue?: number;\n searchTerm?: string;\n transactionId?: string;\n value?: number;\n currency?: string;\n items?: ItemData[];\n itemIds?: string[];\n pageType?: string;\n ecommTotalValue?: number;\n ecommCategory?: string;\n hotelData?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface ItemData {\n id?: string;\n quantity?: number;\n price?: number;\n name?: string;\n}\n\nexport interface ResponseBody {\n status?: string;\n requestId?: string;\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationBing from './types';\n\nexport const destinationBing: Destination = {\n type: 'bing',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationBing;\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$meta": {
3
3
  "package": "@walkeros/server-destination-bing",
4
- "version": "3.4.1",
4
+ "version": "4.0.0-next-1777463920154",
5
5
  "type": "destination",
6
6
  "platform": [
7
7
  "server"
@@ -131,22 +131,16 @@
131
131
  "consent": {
132
132
  "functional": true
133
133
  },
134
- "id": "1700000903000-gr0up-1",
134
+ "id": "b1c2d3e4f5a60004",
135
135
  "trigger": "click",
136
136
  "entity": "product",
137
137
  "action": "add",
138
138
  "timestamp": 1700000903000,
139
139
  "timing": 3.14,
140
- "group": "gr0up",
141
- "count": 1,
142
- "version": {
143
- "source": "3.4.1",
144
- "tagging": 1
145
- },
146
140
  "source": {
147
- "type": "server",
148
- "id": "https://shop.example.com/products/running-shoes",
149
- "previous_id": ""
141
+ "type": "browser",
142
+ "platform": "web",
143
+ "url": "https://shop.example.com/products/running-shoes"
150
144
  }
151
145
  },
152
146
  "mapping": {
@@ -164,7 +158,7 @@
164
158
  "nested",
165
159
  {
166
160
  "condition": {
167
- "$code": "e=>f(e)&&\"product\"===e.entity"
161
+ "$code": "e=>b(e)&&\"product\"===e.entity"
168
162
  },
169
163
  "map": {
170
164
  "id": "data.id",
@@ -187,7 +181,7 @@
187
181
  [
188
182
  "sendServer",
189
183
  "https://capi.uet.microsoft.com/v1/UET-12345/events",
190
- "{\"data\":[{\"eventType\":\"custom\",\"eventId\":\"1700000903000-gr0up-1\",\"eventTime\":1700000903,\"adStorageConsent\":\"G\",\"userData\":{},\"eventName\":\"add_to_cart\",\"eventSourceUrl\":\"https://shop.example.com/products/running-shoes\",\"customData\":{\"value\":89.99,\"currency\":\"EUR\",\"items\":[{\"id\":\"SKU-B2\",\"name\":\"Running Shoes\",\"price\":89.99,\"quantity\":1}]}}],\"dataProvider\":\"walkerOS\"}",
184
+ "{\"data\":[{\"eventType\":\"custom\",\"eventId\":\"b1c2d3e4f5a60004\",\"eventTime\":1700000903,\"adStorageConsent\":\"G\",\"userData\":{},\"eventName\":\"add_to_cart\",\"eventSourceUrl\":\"https://shop.example.com/products/running-shoes\",\"customData\":{\"value\":89.99,\"currency\":\"EUR\",\"items\":[{\"id\":\"SKU-B2\",\"name\":\"Running Shoes\",\"price\":89.99,\"quantity\":1}]}}],\"dataProvider\":\"walkerOS\"}",
191
185
  {
192
186
  "headers": {
193
187
  "Authorization": "Bearer s3cr3t",
@@ -225,35 +219,22 @@
225
219
  "entity": "child",
226
220
  "data": {
227
221
  "is": "subordinated"
228
- },
229
- "nested": [],
230
- "context": {
231
- "element": [
232
- "child",
233
- 0
234
- ]
235
222
  }
236
223
  }
237
224
  ],
238
225
  "consent": {
239
226
  "functional": true
240
227
  },
241
- "id": "1700000902000-gr0up-1",
228
+ "id": "b1c2d3e4f5a60003",
242
229
  "trigger": "test",
243
230
  "entity": "form",
244
231
  "action": "submit",
245
232
  "timestamp": 1700000902000,
246
233
  "timing": 3.14,
247
- "group": "gr0up",
248
- "count": 1,
249
- "version": {
250
- "source": "3.4.1",
251
- "tagging": 1
252
- },
253
234
  "source": {
254
- "type": "server",
255
- "id": "https://example.com/contact",
256
- "previous_id": ""
235
+ "type": "browser",
236
+ "platform": "web",
237
+ "url": "https://example.com/contact"
257
238
  }
258
239
  },
259
240
  "mapping": {
@@ -272,7 +253,7 @@
272
253
  [
273
254
  "sendServer",
274
255
  "https://capi.uet.microsoft.com/v1/UET-12345/events",
275
- "{\"data\":[{\"eventType\":\"custom\",\"eventId\":\"1700000902000-gr0up-1\",\"eventTime\":1700000902,\"adStorageConsent\":\"G\",\"userData\":{\"em\":\"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514\"},\"eventName\":\"lead\",\"eventSourceUrl\":\"https://example.com/contact\"}],\"dataProvider\":\"walkerOS\"}",
256
+ "{\"data\":[{\"eventType\":\"custom\",\"eventId\":\"b1c2d3e4f5a60003\",\"eventTime\":1700000902,\"adStorageConsent\":\"G\",\"userData\":{\"em\":\"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514\"},\"eventName\":\"lead\",\"eventSourceUrl\":\"https://example.com/contact\"}],\"dataProvider\":\"walkerOS\"}",
276
257
  {
277
258
  "headers": {
278
259
  "Authorization": "Bearer s3cr3t",
@@ -317,35 +298,22 @@
317
298
  "entity": "child",
318
299
  "data": {
319
300
  "is": "subordinated"
320
- },
321
- "nested": [],
322
- "context": {
323
- "element": [
324
- "child",
325
- 0
326
- ]
327
301
  }
328
302
  }
329
303
  ],
330
304
  "consent": {
331
305
  "functional": true
332
306
  },
333
- "id": "1700000901000-gr0up-1",
307
+ "id": "b1c2d3e4f5a60002",
334
308
  "trigger": "load",
335
309
  "entity": "page",
336
310
  "action": "view",
337
311
  "timestamp": 1700000901000,
338
312
  "timing": 3.14,
339
- "group": "gr0up",
340
- "count": 1,
341
- "version": {
342
- "source": "3.4.1",
343
- "tagging": 1
344
- },
345
313
  "source": {
346
- "type": "server",
347
- "id": "https://example.com/docs/",
348
- "previous_id": ""
314
+ "type": "browser",
315
+ "platform": "web",
316
+ "url": "https://example.com/docs/"
349
317
  }
350
318
  },
351
319
  "mapping": {
@@ -357,7 +325,7 @@
357
325
  [
358
326
  "sendServer",
359
327
  "https://capi.uet.microsoft.com/v1/UET-12345/events",
360
- "{\"data\":[{\"eventType\":\"pageLoad\",\"eventId\":\"1700000901000-gr0up-1\",\"eventTime\":1700000901,\"adStorageConsent\":\"G\",\"userData\":{},\"eventSourceUrl\":\"https://example.com/docs/\"}],\"dataProvider\":\"walkerOS\"}",
328
+ "{\"data\":[{\"eventType\":\"pageLoad\",\"eventId\":\"b1c2d3e4f5a60002\",\"eventTime\":1700000901,\"adStorageConsent\":\"G\",\"userData\":{},\"eventSourceUrl\":\"https://example.com/docs/\"}],\"dataProvider\":\"walkerOS\"}",
361
329
  {
362
330
  "headers": {
363
331
  "Authorization": "Bearer s3cr3t",
@@ -407,22 +375,16 @@
407
375
  "consent": {
408
376
  "functional": true
409
377
  },
410
- "id": "1700000900000-gr0up-1",
378
+ "id": "b1c2d3e4f5a60001",
411
379
  "trigger": "load",
412
380
  "entity": "order",
413
381
  "action": "complete",
414
382
  "timestamp": 1700000900000,
415
383
  "timing": 3.14,
416
- "group": "gr0up",
417
- "count": 1,
418
- "version": {
419
- "source": "3.4.1",
420
- "tagging": 1
421
- },
422
384
  "source": {
423
- "type": "server",
424
- "id": "https://shop.example.com/checkout/complete",
425
- "previous_id": ""
385
+ "type": "browser",
386
+ "platform": "web",
387
+ "url": "https://shop.example.com/checkout/complete"
426
388
  }
427
389
  },
428
390
  "mapping": {
@@ -445,7 +407,7 @@
445
407
  "nested",
446
408
  {
447
409
  "condition": {
448
- "$code": "e=>f(e)&&\"product\"===e.entity"
410
+ "$code": "e=>b(e)&&\"product\"===e.entity"
449
411
  },
450
412
  "map": {
451
413
  "id": "data.id",
@@ -473,7 +435,7 @@
473
435
  [
474
436
  "sendServer",
475
437
  "https://capi.uet.microsoft.com/v1/UET-12345/events",
476
- "{\"data\":[{\"eventType\":\"custom\",\"eventId\":\"1700000900000-gr0up-1\",\"eventTime\":1700000900,\"adStorageConsent\":\"G\",\"userData\":{\"externalId\":\"user-123\"},\"eventName\":\"purchase\",\"eventSourceUrl\":\"https://shop.example.com/checkout/complete\",\"customData\":{\"value\":249.99,\"currency\":\"EUR\",\"transactionId\":\"ORD-300\",\"pageType\":\"purchase\",\"items\":[{\"id\":\"SKU-A1\",\"name\":\"Widget Pro\",\"price\":124.99,\"quantity\":2}]}}],\"dataProvider\":\"walkerOS\"}",
438
+ "{\"data\":[{\"eventType\":\"custom\",\"eventId\":\"b1c2d3e4f5a60001\",\"eventTime\":1700000900,\"adStorageConsent\":\"G\",\"userData\":{\"externalId\":\"user-123\"},\"eventName\":\"purchase\",\"eventSourceUrl\":\"https://shop.example.com/checkout/complete\",\"customData\":{\"value\":249.99,\"currency\":\"EUR\",\"transactionId\":\"ORD-300\",\"pageType\":\"purchase\",\"items\":[{\"id\":\"SKU-A1\",\"name\":\"Widget Pro\",\"price\":124.99,\"quantity\":2}]}}],\"dataProvider\":\"walkerOS\"}",
477
439
  {
478
440
  "headers": {
479
441
  "Authorization": "Bearer s3cr3t",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walkeros/server-destination-bing",
3
3
  "description": "Microsoft Advertising (Bing UET CAPI) server destination for walkerOS",
4
- "version": "3.4.1",
4
+ "version": "4.0.0-next-1777463920154",
5
5
  "license": "MIT",
6
6
  "exports": {
7
7
  ".": {
@@ -34,11 +34,11 @@
34
34
  "update": "npx npm-check-updates -u && npm update"
35
35
  },
36
36
  "dependencies": {
37
- "@walkeros/core": "3.4.1",
38
- "@walkeros/server-core": "3.4.1"
37
+ "@walkeros/core": "4.0.0-next-1777463920154",
38
+ "@walkeros/server-core": "4.0.0-next-1777463920154"
39
39
  },
40
40
  "devDependencies": {
41
- "@walkeros/collector": "3.4.1"
41
+ "@walkeros/collector": "4.0.0-next-1777463920154"
42
42
  },
43
43
  "repository": {
44
44
  "url": "git+https://github.com/elbwalker/walkerOS.git",