@walkeros/server-destination-criteo 3.4.2 → 4.0.0-next-1777882869103
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 +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.js +13 -12
- package/dist/examples/index.mjs +13 -12
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +21 -51
- package/package.json +4 -4
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,i=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,o=(e,i)=>{for(var r in i)t(e,r,{get:i[r],enumerable:!0})},n={};o(n,{examples:()=>y,schemas:()=>s}),module.exports=(e=n,((e,o,n,s)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,i=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,o=(e,i)=>{for(var r in i)t(e,r,{get:i[r],enumerable:!0})},n={};o(n,{examples:()=>y,schemas:()=>s}),module.exports=(e=n,((e,o,n,s)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let p of r(o))a.call(e,p)||p===n||t(e,p,{get:()=>o[p],enumerable:!(s=i(o,p))||s.enumerable});return e})(t({},"__esModule",{value:!0}),e));var s={};o(s,{CriteoEventNameSchema:()=>l,MappingSchema:()=>m,SettingsSchema:()=>c,mapping:()=>g,settings:()=>v});var p=require("@walkeros/core/dev"),d=require("@walkeros/core/dev"),c=d.z.object({partnerId:d.z.string().min(1).describe("Criteo Partner ID (numeric string, provided by Criteo)"),callerId:d.z.string().min(1).describe("Caller ID for user mapping (provided by Criteo)"),siteType:d.z.enum(["d","m","t"]).describe("Site type: d (desktop), m (mobile web), t (tablet)").optional(),country:d.z.string().length(2).describe("ISO 3166-1 alpha-2 country code").optional(),language:d.z.string().length(2).describe("2-letter language code").optional(),url:d.z.string().url().describe("Custom Events API endpoint (default https://widget.criteo.com/m/event?version=s2s_v0)").optional(),user_data:d.z.record(d.z.string(),d.z.string()).describe("Mapping for identity fields (like { email: 'user.email', mapped_user_id: 'user.id' })").optional()}),m=require("@walkeros/core/dev").z.object({}),u=require("@walkeros/core/dev"),l=u.z.union([u.z.enum(["viewHome","viewPage","viewItem","viewList","addToCart","viewBasket","beginCheckout","trackTransaction","addPaymentInfo","login"]),u.z.string()]),v=(0,p.zodToSchema)(c),g=(0,p.zodToSchema)(m),y={};o(y,{env:()=>h,step:()=>_});var h={};o(h,{push:()=>w,simulation:()=>b});var w={sendServer:async()=>({ok:!0,data:"OK"})},b=["sendServer"],_={};o(_,{addToCart:()=>C,pageView:()=>T,purchase:()=>S,viewItem:()=>I});var f=require("@walkeros/core"),k="https://widget.criteo.com/m/event?version=s2s_v0",S={title:"Purchase",description:"A completed order is posted to the Criteo Events API as a trackTransaction event with items.",in:(0,f.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:"browser",platform:"web",url:"https://shop.example.com/checkout/complete",referrer:"https://shop.example.com/cart"}}),mapping:{name:"trackTransaction",data:{map:{id:"data.id",item:{loop:["nested",{condition:e=>(0,f.isObject)(e)&&"product"===e.entity,map:{id:"data.id",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}},out:[["sendServer",k,JSON.stringify({version:"walkeros_criteo_1.0.0",site_type:"d",account:"PARTNER_ID",id:{mapping_key:"CALLER_ID"},events:[{event:"trackTransaction",timestamp:"2023-11-14T22:28:20.000Z",id:"ORD-300",item:[{id:"SKU-A1",price:124.99,quantity:2}]}],full_url:"https://shop.example.com/checkout/complete",previous_url:"https://shop.example.com/cart"})]]},C={title:"Add to cart",description:"A product add becomes a Criteo addToCart event with the item id, price, and quantity.",in:(0,f.getEvent)("product add",{timestamp:1700000901e3,data:{id:"SKU-B2",name:"Running Shoes",price:89.99},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:"addToCart",data:{map:{item:{loop:["nested",{condition:e=>(0,f.isObject)(e)&&"product"===e.entity,map:{id:"data.id",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}},out:[["sendServer",k,JSON.stringify({version:"walkeros_criteo_1.0.0",site_type:"d",account:"PARTNER_ID",id:{mapping_key:"CALLER_ID"},events:[{event:"addToCart",timestamp:"2023-11-14T22:28:21.000Z",item:[{id:"SKU-B2",price:89.99,quantity:1}]}],full_url:"https://shop.example.com/products/running-shoes"})]]},I={title:"View item",description:"A product view becomes a Criteo viewItem event with the viewed product id.",in:(0,f.getEvent)("product view",{timestamp:1700000902e3,data:{id:"SKU-C3",name:"Coffee Maker"},nested:[{entity:"product",data:{id:"SKU-C3"}}],source:{type:"browser",platform:"web",url:"https://shop.example.com/products/coffee-maker"}}),mapping:{name:"viewItem",data:{map:{item:{loop:["nested",{condition:e=>(0,f.isObject)(e)&&"product"===e.entity,map:{id:"data.id"}}]}}}},out:[["sendServer",k,JSON.stringify({version:"walkeros_criteo_1.0.0",site_type:"d",account:"PARTNER_ID",id:{mapping_key:"CALLER_ID"},events:[{event:"viewItem",timestamp:"2023-11-14T22:28:22.000Z",item:[{id:"SKU-C3"}]}],full_url:"https://shop.example.com/products/coffee-maker"})]]},T={title:"Page view",description:"A page view becomes a Criteo viewHome event used for home page impression tracking.",in:(0,f.getEvent)("page view",{timestamp:1700000903e3,source:{type:"browser",platform:"web",url:"https://example.com/"}}),mapping:{name:"viewHome"},out:[["sendServer",k,JSON.stringify({version:"walkeros_criteo_1.0.0",site_type:"d",account:"PARTNER_ID",id:{mapping_key:"CALLER_ID"},events:[{event:"viewHome",timestamp:"2023-11-14T22:28:23.000Z"}],full_url:"https://example.com/"})]]};//# 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 partnerId: z\n .string()\n .min(1)\n .describe('Criteo Partner ID (numeric string, provided by Criteo)'),\n callerId: z\n .string()\n .min(1)\n .describe('Caller ID for user mapping (provided by Criteo)'),\n siteType: z\n .enum(['d', 'm', 't'])\n .describe('Site type: d (desktop), m (mobile web), t (tablet)')\n .optional(),\n country: z\n .string()\n .length(2)\n .describe('ISO 3166-1 alpha-2 country code')\n .optional(),\n language: z.string().length(2).describe('2-letter language code').optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom Events API endpoint (default https://widget.criteo.com/m/event?version=s2s_v0)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping for identity fields (like { email: 'user.email', mapped_user_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Criteo Events API Mapping Schema\n * Criteo has no event-level mapping configuration beyond name + data\n */\nexport const MappingSchema = z.object({});\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 * Standard Criteo Events API event names.\n * https://guides.criteotilt.com/events-api/\n */\nexport const CriteoEventNameSchema = z.union([\n z.enum([\n 'viewHome',\n 'viewPage',\n 'viewItem',\n 'viewList',\n 'addToCart',\n 'viewBasket',\n 'beginCheckout',\n 'trackTransaction',\n 'addPaymentInfo',\n 'login',\n ]),\n z.string(), // Allow custom event names\n]);\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 Criteo Events API 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: 'OK',\n});\n\n/**\n * Standard mock environment for push operations.\n *\n * Use this for testing Criteo Events API pushes without making\n * actual HTTP requests to Criteo'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 * Criteo Events API step examples.\n *\n * At push time, the destination calls `env.sendServer(url, body)` where\n * `url` is the configured Criteo endpoint (default:\n * `https://widget.criteo.com/m/event?version=s2s_v0`) and `body` is the\n * JSON-stringified request payload.\n *\n * Test fixture pins `partnerId = 'PARTNER_ID'` and `callerId = 'CALLER_ID'`,\n * so every call targets the default URL above.\n *\n * Body is emitted with keys in the order the destination assembles them:\n * 1. version\n * 2. site_type\n * 3. account\n * 4. id (identity block)\n * 5. events (always a single-element array)\n * 6. full_url (only when event.source.id is set)\n * 7. previous_url (only when event.source.previous_id is set)\n */\nconst ENDPOINT = 'https://widget.criteo.com/m/event?version=s2s_v0';\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is posted to the Criteo Events API as a trackTransaction event with items.',\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: 'https://shop.example.com/cart',\n },\n }),\n mapping: {\n name: 'trackTransaction',\n data: {\n map: {\n id: 'data.id',\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'trackTransaction',\n timestamp: '2023-11-14T22:28:20.000Z',\n id: 'ORD-300',\n item: [\n {\n id: 'SKU-A1',\n price: 124.99,\n quantity: 2,\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/checkout/complete',\n previous_url: 'https://shop.example.com/cart',\n }),\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add becomes a Criteo addToCart event with the item id, price, and quantity.',\n in: getEvent('product add', {\n timestamp: 1700000901000,\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\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: 'addToCart',\n data: {\n map: {\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'addToCart',\n timestamp: '2023-11-14T22:28:21.000Z',\n item: [\n {\n id: 'SKU-B2',\n price: 89.99,\n quantity: 1,\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/products/running-shoes',\n }),\n ],\n ],\n};\n\nexport const viewItem: Flow.StepExample = {\n title: 'View item',\n description:\n 'A product view becomes a Criteo viewItem event with the viewed product id.',\n in: getEvent('product view', {\n timestamp: 1700000902000,\n data: { id: 'SKU-C3', name: 'Coffee Maker' },\n nested: [\n {\n entity: 'product',\n data: { id: 'SKU-C3' },\n },\n ],\n source: {\n type: 'server',\n id: 'https://shop.example.com/products/coffee-maker',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'viewItem',\n data: {\n map: {\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'viewItem',\n timestamp: '2023-11-14T22:28:22.000Z',\n item: [\n {\n id: 'SKU-C3',\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/products/coffee-maker',\n }),\n ],\n ],\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page view becomes a Criteo viewHome event used for home page impression tracking.',\n in: getEvent('page view', {\n timestamp: 1700000903000,\n source: {\n type: 'server',\n id: 'https://example.com/',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'viewHome',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'viewHome',\n timestamp: '2023-11-14T22:28:23.000Z',\n },\n ],\n full_url: 'https://example.com/',\n }),\n ],\n ],\n};\n"],"mappings":"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","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 partnerId: z\n .string()\n .min(1)\n .describe('Criteo Partner ID (numeric string, provided by Criteo)'),\n callerId: z\n .string()\n .min(1)\n .describe('Caller ID for user mapping (provided by Criteo)'),\n siteType: z\n .enum(['d', 'm', 't'])\n .describe('Site type: d (desktop), m (mobile web), t (tablet)')\n .optional(),\n country: z\n .string()\n .length(2)\n .describe('ISO 3166-1 alpha-2 country code')\n .optional(),\n language: z.string().length(2).describe('2-letter language code').optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom Events API endpoint (default https://widget.criteo.com/m/event?version=s2s_v0)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping for identity fields (like { email: 'user.email', mapped_user_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Criteo Events API Mapping Schema\n * Criteo has no event-level mapping configuration beyond name + data\n */\nexport const MappingSchema = z.object({});\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 * Standard Criteo Events API event names.\n * https://guides.criteotilt.com/events-api/\n */\nexport const CriteoEventNameSchema = z.union([\n z.enum([\n 'viewHome',\n 'viewPage',\n 'viewItem',\n 'viewList',\n 'addToCart',\n 'viewBasket',\n 'beginCheckout',\n 'trackTransaction',\n 'addPaymentInfo',\n 'login',\n ]),\n z.string(), // Allow custom event names\n]);\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 Criteo Events API 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: 'OK',\n});\n\n/**\n * Standard mock environment for push operations.\n *\n * Use this for testing Criteo Events API pushes without making\n * actual HTTP requests to Criteo'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 * Criteo Events API step examples.\n *\n * At push time, the destination calls `env.sendServer(url, body)` where\n * `url` is the configured Criteo endpoint (default:\n * `https://widget.criteo.com/m/event?version=s2s_v0`) and `body` is the\n * JSON-stringified request payload.\n *\n * Test fixture pins `partnerId = 'PARTNER_ID'` and `callerId = 'CALLER_ID'`,\n * so every call targets the default URL above.\n *\n * Body is emitted with keys in the order the destination assembles them:\n * 1. version\n * 2. site_type\n * 3. account\n * 4. id (identity block)\n * 5. events (always a single-element array)\n * 6. full_url (only when event.source.url is set)\n * 7. previous_url (only when event.source.referrer is set)\n */\nconst ENDPOINT = 'https://widget.criteo.com/m/event?version=s2s_v0';\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is posted to the Criteo Events API as a trackTransaction event with items.',\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: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/checkout/complete',\n referrer: 'https://shop.example.com/cart',\n },\n }),\n mapping: {\n name: 'trackTransaction',\n data: {\n map: {\n id: 'data.id',\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'trackTransaction',\n timestamp: '2023-11-14T22:28:20.000Z',\n id: 'ORD-300',\n item: [\n {\n id: 'SKU-A1',\n price: 124.99,\n quantity: 2,\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/checkout/complete',\n previous_url: 'https://shop.example.com/cart',\n }),\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add becomes a Criteo addToCart event with the item id, price, and quantity.',\n in: getEvent('product add', {\n timestamp: 1700000901000,\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\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: 'addToCart',\n data: {\n map: {\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'addToCart',\n timestamp: '2023-11-14T22:28:21.000Z',\n item: [\n {\n id: 'SKU-B2',\n price: 89.99,\n quantity: 1,\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/products/running-shoes',\n }),\n ],\n ],\n};\n\nexport const viewItem: Flow.StepExample = {\n title: 'View item',\n description:\n 'A product view becomes a Criteo viewItem event with the viewed product id.',\n in: getEvent('product view', {\n timestamp: 1700000902000,\n data: { id: 'SKU-C3', name: 'Coffee Maker' },\n nested: [\n {\n entity: 'product',\n data: { id: 'SKU-C3' },\n },\n ],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/products/coffee-maker',\n },\n }),\n mapping: {\n name: 'viewItem',\n data: {\n map: {\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'viewItem',\n timestamp: '2023-11-14T22:28:22.000Z',\n item: [\n {\n id: 'SKU-C3',\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/products/coffee-maker',\n }),\n ],\n ],\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page view becomes a Criteo viewHome event used for home page impression tracking.',\n in: getEvent('page view', {\n timestamp: 1700000903000,\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n },\n }),\n mapping: {\n name: 'viewHome',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'viewHome',\n timestamp: '2023-11-14T22:28:23.000Z',\n },\n ],\n full_url: 'https://example.com/',\n }),\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,i)=>{for(var r in i)e(t,r,{get:i[r],enumerable:!0})},i={};t(i,{CriteoEventNameSchema:()=>
|
|
1
|
+
var e=Object.defineProperty,t=(t,i)=>{for(var r in i)e(t,r,{get:i[r],enumerable:!0})},i={};t(i,{CriteoEventNameSchema:()=>d,MappingSchema:()=>s,SettingsSchema:()=>o,mapping:()=>c,settings:()=>m});import{zodToSchema as r}from"@walkeros/core/dev";import{z as a}from"@walkeros/core/dev";var o=a.object({partnerId:a.string().min(1).describe("Criteo Partner ID (numeric string, provided by Criteo)"),callerId:a.string().min(1).describe("Caller ID for user mapping (provided by Criteo)"),siteType:a.enum(["d","m","t"]).describe("Site type: d (desktop), m (mobile web), t (tablet)").optional(),country:a.string().length(2).describe("ISO 3166-1 alpha-2 country code").optional(),language:a.string().length(2).describe("2-letter language code").optional(),url:a.string().url().describe("Custom Events API endpoint (default https://widget.criteo.com/m/event?version=s2s_v0)").optional(),user_data:a.record(a.string(),a.string()).describe("Mapping for identity fields (like { email: 'user.email', mapped_user_id: 'user.id' })").optional()});import{z as n}from"@walkeros/core/dev";var s=n.object({});import{z as p}from"@walkeros/core/dev";var d=p.union([p.enum(["viewHome","viewPage","viewItem","viewList","addToCart","viewBasket","beginCheckout","trackTransaction","addPaymentInfo","login"]),p.string()]),m=r(o),c=r(s),u={};t(u,{env:()=>l,step:()=>h});var l={};t(l,{push:()=>v,simulation:()=>g});var v={sendServer:async()=>({ok:!0,data:"OK"})},g=["sendServer"],h={};t(h,{addToCart:()=>k,pageView:()=>S,purchase:()=>f,viewItem:()=>b});import{getEvent as y,isObject as w}from"@walkeros/core";var _="https://widget.criteo.com/m/event?version=s2s_v0",f={title:"Purchase",description:"A completed order is posted to the Criteo Events API as a trackTransaction event with items.",in:y("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:"browser",platform:"web",url:"https://shop.example.com/checkout/complete",referrer:"https://shop.example.com/cart"}}),mapping:{name:"trackTransaction",data:{map:{id:"data.id",item:{loop:["nested",{condition:e=>w(e)&&"product"===e.entity,map:{id:"data.id",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}},out:[["sendServer",_,JSON.stringify({version:"walkeros_criteo_1.0.0",site_type:"d",account:"PARTNER_ID",id:{mapping_key:"CALLER_ID"},events:[{event:"trackTransaction",timestamp:"2023-11-14T22:28:20.000Z",id:"ORD-300",item:[{id:"SKU-A1",price:124.99,quantity:2}]}],full_url:"https://shop.example.com/checkout/complete",previous_url:"https://shop.example.com/cart"})]]},k={title:"Add to cart",description:"A product add becomes a Criteo addToCart event with the item id, price, and quantity.",in:y("product add",{timestamp:1700000901e3,data:{id:"SKU-B2",name:"Running Shoes",price:89.99},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:"addToCart",data:{map:{item:{loop:["nested",{condition:e=>w(e)&&"product"===e.entity,map:{id:"data.id",price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}},out:[["sendServer",_,JSON.stringify({version:"walkeros_criteo_1.0.0",site_type:"d",account:"PARTNER_ID",id:{mapping_key:"CALLER_ID"},events:[{event:"addToCart",timestamp:"2023-11-14T22:28:21.000Z",item:[{id:"SKU-B2",price:89.99,quantity:1}]}],full_url:"https://shop.example.com/products/running-shoes"})]]},b={title:"View item",description:"A product view becomes a Criteo viewItem event with the viewed product id.",in:y("product view",{timestamp:1700000902e3,data:{id:"SKU-C3",name:"Coffee Maker"},nested:[{entity:"product",data:{id:"SKU-C3"}}],source:{type:"browser",platform:"web",url:"https://shop.example.com/products/coffee-maker"}}),mapping:{name:"viewItem",data:{map:{item:{loop:["nested",{condition:e=>w(e)&&"product"===e.entity,map:{id:"data.id"}}]}}}},out:[["sendServer",_,JSON.stringify({version:"walkeros_criteo_1.0.0",site_type:"d",account:"PARTNER_ID",id:{mapping_key:"CALLER_ID"},events:[{event:"viewItem",timestamp:"2023-11-14T22:28:22.000Z",item:[{id:"SKU-C3"}]}],full_url:"https://shop.example.com/products/coffee-maker"})]]},S={title:"Page view",description:"A page view becomes a Criteo viewHome event used for home page impression tracking.",in:y("page view",{timestamp:1700000903e3,source:{type:"browser",platform:"web",url:"https://example.com/"}}),mapping:{name:"viewHome"},out:[["sendServer",_,JSON.stringify({version:"walkeros_criteo_1.0.0",site_type:"d",account:"PARTNER_ID",id:{mapping_key:"CALLER_ID"},events:[{event:"viewHome",timestamp:"2023-11-14T22:28:23.000Z"}],full_url:"https://example.com/"})]]};export{u as examples,i as schemas};//# sourceMappingURL=dev.mjs.map
|
package/dist/dev.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/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 partnerId: z\n .string()\n .min(1)\n .describe('Criteo Partner ID (numeric string, provided by Criteo)'),\n callerId: z\n .string()\n .min(1)\n .describe('Caller ID for user mapping (provided by Criteo)'),\n siteType: z\n .enum(['d', 'm', 't'])\n .describe('Site type: d (desktop), m (mobile web), t (tablet)')\n .optional(),\n country: z\n .string()\n .length(2)\n .describe('ISO 3166-1 alpha-2 country code')\n .optional(),\n language: z.string().length(2).describe('2-letter language code').optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom Events API endpoint (default https://widget.criteo.com/m/event?version=s2s_v0)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping for identity fields (like { email: 'user.email', mapped_user_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Criteo Events API Mapping Schema\n * Criteo has no event-level mapping configuration beyond name + data\n */\nexport const MappingSchema = z.object({});\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 * Standard Criteo Events API event names.\n * https://guides.criteotilt.com/events-api/\n */\nexport const CriteoEventNameSchema = z.union([\n z.enum([\n 'viewHome',\n 'viewPage',\n 'viewItem',\n 'viewList',\n 'addToCart',\n 'viewBasket',\n 'beginCheckout',\n 'trackTransaction',\n 'addPaymentInfo',\n 'login',\n ]),\n z.string(), // Allow custom event names\n]);\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 Criteo Events API 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: 'OK',\n});\n\n/**\n * Standard mock environment for push operations.\n *\n * Use this for testing Criteo Events API pushes without making\n * actual HTTP requests to Criteo'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 * Criteo Events API step examples.\n *\n * At push time, the destination calls `env.sendServer(url, body)` where\n * `url` is the configured Criteo endpoint (default:\n * `https://widget.criteo.com/m/event?version=s2s_v0`) and `body` is the\n * JSON-stringified request payload.\n *\n * Test fixture pins `partnerId = 'PARTNER_ID'` and `callerId = 'CALLER_ID'`,\n * so every call targets the default URL above.\n *\n * Body is emitted with keys in the order the destination assembles them:\n * 1. version\n * 2. site_type\n * 3. account\n * 4. id (identity block)\n * 5. events (always a single-element array)\n * 6. full_url (only when event.source.id is set)\n * 7. previous_url (only when event.source.previous_id is set)\n */\nconst ENDPOINT = 'https://widget.criteo.com/m/event?version=s2s_v0';\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is posted to the Criteo Events API as a trackTransaction event with items.',\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: 'https://shop.example.com/cart',\n },\n }),\n mapping: {\n name: 'trackTransaction',\n data: {\n map: {\n id: 'data.id',\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'trackTransaction',\n timestamp: '2023-11-14T22:28:20.000Z',\n id: 'ORD-300',\n item: [\n {\n id: 'SKU-A1',\n price: 124.99,\n quantity: 2,\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/checkout/complete',\n previous_url: 'https://shop.example.com/cart',\n }),\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add becomes a Criteo addToCart event with the item id, price, and quantity.',\n in: getEvent('product add', {\n timestamp: 1700000901000,\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\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: 'addToCart',\n data: {\n map: {\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'addToCart',\n timestamp: '2023-11-14T22:28:21.000Z',\n item: [\n {\n id: 'SKU-B2',\n price: 89.99,\n quantity: 1,\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/products/running-shoes',\n }),\n ],\n ],\n};\n\nexport const viewItem: Flow.StepExample = {\n title: 'View item',\n description:\n 'A product view becomes a Criteo viewItem event with the viewed product id.',\n in: getEvent('product view', {\n timestamp: 1700000902000,\n data: { id: 'SKU-C3', name: 'Coffee Maker' },\n nested: [\n {\n entity: 'product',\n data: { id: 'SKU-C3' },\n },\n ],\n source: {\n type: 'server',\n id: 'https://shop.example.com/products/coffee-maker',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'viewItem',\n data: {\n map: {\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'viewItem',\n timestamp: '2023-11-14T22:28:22.000Z',\n item: [\n {\n id: 'SKU-C3',\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/products/coffee-maker',\n }),\n ],\n ],\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page view becomes a Criteo viewHome event used for home page impression tracking.',\n in: getEvent('page view', {\n timestamp: 1700000903000,\n source: {\n type: 'server',\n id: 'https://example.com/',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'viewHome',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'viewHome',\n timestamp: '2023-11-14T22:28:23.000Z',\n },\n ],\n full_url: 'https://example.com/',\n }),\n ],\n ],\n};\n"],"mappings":";;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,mBAAmB;;;ACA5B,SAAS,SAAS;AAEX,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,WAAW,EACR,OAAO,EACP,IAAI,CAAC,EACL,SAAS,wDAAwD;AAAA,EACpE,UAAU,EACP,OAAO,EACP,IAAI,CAAC,EACL,SAAS,iDAAiD;AAAA,EAC7D,UAAU,EACP,KAAK,CAAC,KAAK,KAAK,GAAG,CAAC,EACpB,SAAS,oDAAoD,EAC7D,SAAS;AAAA,EACZ,SAAS,EACN,OAAO,EACP,OAAO,CAAC,EACR,SAAS,iCAAiC,EAC1C,SAAS;AAAA,EACZ,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS,wBAAwB,EAAE,SAAS;AAAA,EAC3E,KAAK,EACF,OAAO,EACP,IAAI,EACJ;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,WAAW,EACR,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAC7B;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;AClCD,SAAS,KAAAA,UAAS;AAMX,IAAM,gBAAgBA,GAAE,OAAO,CAAC,CAAC;;;ACNxC,SAAS,KAAAC,UAAS;AAMX,IAAM,wBAAwBA,GAAE,MAAM;AAAA,EAC3CA,GAAE,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EACDA,GAAE,OAAO;AAAA;AACX,CAAC;;;AHVM,IAAM,WAAW,YAAY,cAAc;AAC3C,IAAM,UAAU,YAAY,aAAa;;;AIXhD;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAiBA,IAAM,iBAAiC,aAAa;AAAA,EAClD,IAAI;AAAA,EACJ,MAAM;AACR;AAQO,IAAM,OAAY;AAAA,EACvB,YAAY;AACd;AAEO,IAAM,aAAa,CAAC,YAAY;;;AChCvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,SAAS,UAAU,gBAAgB;AAsBnC,IAAM,WAAW;AAEV,IAAM,WAA6B;AAAA,EACxC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,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,IAAI;AAAA,QACJ,MAAM;AAAA,UACJ,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,cACE,WAAW,CAAC,WACV,SAAS,MAAM,KAAK,OAAO,WAAW;AAAA,cACxC,KAAK;AAAA,gBACH,IAAI;AAAA,gBACJ,OAAO;AAAA,gBACP,UAAU,EAAE,KAAK,iBAAiB,OAAO,EAAE;AAAA,cAC7C;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,SAAS;AAAA,QACT,WAAW;AAAA,QACX,SAAS;AAAA,QACT,IAAI;AAAA,UACF,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN;AAAA,YACE,OAAO;AAAA,YACP,WAAW;AAAA,YACX,IAAI;AAAA,YACJ,MAAM;AAAA,cACJ;AAAA,gBACE,IAAI;AAAA,gBACJ,OAAO;AAAA,gBACP,UAAU;AAAA,cACZ;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,UAAU;AAAA,QACV,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,IAAM,YAA8B;AAAA,EACzC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,eAAe;AAAA,IAC1B,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,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,MAAM;AAAA,UACJ,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,cACE,WAAW,CAAC,WACV,SAAS,MAAM,KAAK,OAAO,WAAW;AAAA,cACxC,KAAK;AAAA,gBACH,IAAI;AAAA,gBACJ,OAAO;AAAA,gBACP,UAAU,EAAE,KAAK,iBAAiB,OAAO,EAAE;AAAA,cAC7C;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,SAAS;AAAA,QACT,WAAW;AAAA,QACX,SAAS;AAAA,QACT,IAAI;AAAA,UACF,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN;AAAA,YACE,OAAO;AAAA,YACP,WAAW;AAAA,YACX,MAAM;AAAA,cACJ;AAAA,gBACE,IAAI;AAAA,gBACJ,OAAO;AAAA,gBACP,UAAU;AAAA,cACZ;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,IAAM,WAA6B;AAAA,EACxC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,gBAAgB;AAAA,IAC3B,WAAW;AAAA,IACX,MAAM,EAAE,IAAI,UAAU,MAAM,eAAe;AAAA,IAC3C,QAAQ;AAAA,MACN;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,EAAE,IAAI,SAAS;AAAA,MACvB;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,MAAM;AAAA,UACJ,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,cACE,WAAW,CAAC,WACV,SAAS,MAAM,KAAK,OAAO,WAAW;AAAA,cACxC,KAAK;AAAA,gBACH,IAAI;AAAA,cACN;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,SAAS;AAAA,QACT,WAAW;AAAA,QACX,SAAS;AAAA,QACT,IAAI;AAAA,UACF,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN;AAAA,YACE,OAAO;AAAA,YACP,WAAW;AAAA,YACX,MAAM;AAAA,cACJ;AAAA,gBACE,IAAI;AAAA,cACN;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,IAAM,WAA6B;AAAA,EACxC,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,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,MAAM;AAAA,EACR;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK,UAAU;AAAA,QACb,SAAS;AAAA,QACT,WAAW;AAAA,QACX,SAAS;AAAA,QACT,IAAI;AAAA,UACF,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN;AAAA,YACE,OAAO;AAAA,YACP,WAAW;AAAA,UACb;AAAA,QACF;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":["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 partnerId: z\n .string()\n .min(1)\n .describe('Criteo Partner ID (numeric string, provided by Criteo)'),\n callerId: z\n .string()\n .min(1)\n .describe('Caller ID for user mapping (provided by Criteo)'),\n siteType: z\n .enum(['d', 'm', 't'])\n .describe('Site type: d (desktop), m (mobile web), t (tablet)')\n .optional(),\n country: z\n .string()\n .length(2)\n .describe('ISO 3166-1 alpha-2 country code')\n .optional(),\n language: z.string().length(2).describe('2-letter language code').optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom Events API endpoint (default https://widget.criteo.com/m/event?version=s2s_v0)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping for identity fields (like { email: 'user.email', mapped_user_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Criteo Events API Mapping Schema\n * Criteo has no event-level mapping configuration beyond name + data\n */\nexport const MappingSchema = z.object({});\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 * Standard Criteo Events API event names.\n * https://guides.criteotilt.com/events-api/\n */\nexport const CriteoEventNameSchema = z.union([\n z.enum([\n 'viewHome',\n 'viewPage',\n 'viewItem',\n 'viewList',\n 'addToCart',\n 'viewBasket',\n 'beginCheckout',\n 'trackTransaction',\n 'addPaymentInfo',\n 'login',\n ]),\n z.string(), // Allow custom event names\n]);\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 Criteo Events API 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: 'OK',\n});\n\n/**\n * Standard mock environment for push operations.\n *\n * Use this for testing Criteo Events API pushes without making\n * actual HTTP requests to Criteo'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 * Criteo Events API step examples.\n *\n * At push time, the destination calls `env.sendServer(url, body)` where\n * `url` is the configured Criteo endpoint (default:\n * `https://widget.criteo.com/m/event?version=s2s_v0`) and `body` is the\n * JSON-stringified request payload.\n *\n * Test fixture pins `partnerId = 'PARTNER_ID'` and `callerId = 'CALLER_ID'`,\n * so every call targets the default URL above.\n *\n * Body is emitted with keys in the order the destination assembles them:\n * 1. version\n * 2. site_type\n * 3. account\n * 4. id (identity block)\n * 5. events (always a single-element array)\n * 6. full_url (only when event.source.url is set)\n * 7. previous_url (only when event.source.referrer is set)\n */\nconst ENDPOINT = 'https://widget.criteo.com/m/event?version=s2s_v0';\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is posted to the Criteo Events API as a trackTransaction event with items.',\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: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/checkout/complete',\n referrer: 'https://shop.example.com/cart',\n },\n }),\n mapping: {\n name: 'trackTransaction',\n data: {\n map: {\n id: 'data.id',\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'trackTransaction',\n timestamp: '2023-11-14T22:28:20.000Z',\n id: 'ORD-300',\n item: [\n {\n id: 'SKU-A1',\n price: 124.99,\n quantity: 2,\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/checkout/complete',\n previous_url: 'https://shop.example.com/cart',\n }),\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add becomes a Criteo addToCart event with the item id, price, and quantity.',\n in: getEvent('product add', {\n timestamp: 1700000901000,\n data: {\n id: 'SKU-B2',\n name: 'Running Shoes',\n price: 89.99,\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: 'addToCart',\n data: {\n map: {\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'addToCart',\n timestamp: '2023-11-14T22:28:21.000Z',\n item: [\n {\n id: 'SKU-B2',\n price: 89.99,\n quantity: 1,\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/products/running-shoes',\n }),\n ],\n ],\n};\n\nexport const viewItem: Flow.StepExample = {\n title: 'View item',\n description:\n 'A product view becomes a Criteo viewItem event with the viewed product id.',\n in: getEvent('product view', {\n timestamp: 1700000902000,\n data: { id: 'SKU-C3', name: 'Coffee Maker' },\n nested: [\n {\n entity: 'product',\n data: { id: 'SKU-C3' },\n },\n ],\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/products/coffee-maker',\n },\n }),\n mapping: {\n name: 'viewItem',\n data: {\n map: {\n item: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n },\n },\n ],\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'viewItem',\n timestamp: '2023-11-14T22:28:22.000Z',\n item: [\n {\n id: 'SKU-C3',\n },\n ],\n },\n ],\n full_url: 'https://shop.example.com/products/coffee-maker',\n }),\n ],\n ],\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A page view becomes a Criteo viewHome event used for home page impression tracking.',\n in: getEvent('page view', {\n timestamp: 1700000903000,\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://example.com/',\n },\n }),\n mapping: {\n name: 'viewHome',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n version: 'walkeros_criteo_1.0.0',\n site_type: 'd',\n account: 'PARTNER_ID',\n id: {\n mapping_key: 'CALLER_ID',\n },\n events: [\n {\n event: 'viewHome',\n timestamp: '2023-11-14T22:28:23.000Z',\n },\n ],\n full_url: 'https://example.com/',\n }),\n ],\n ],\n};\n"],"mappings":"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","names":["z","z"]}
|
package/dist/examples/index.js
CHANGED
|
@@ -64,9 +64,10 @@ var purchase = {
|
|
|
64
64
|
],
|
|
65
65
|
user: { id: "user-123", device: "device-456" },
|
|
66
66
|
source: {
|
|
67
|
-
type: "
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
type: "browser",
|
|
68
|
+
platform: "web",
|
|
69
|
+
url: "https://shop.example.com/checkout/complete",
|
|
70
|
+
referrer: "https://shop.example.com/cart"
|
|
70
71
|
}
|
|
71
72
|
}),
|
|
72
73
|
mapping: {
|
|
@@ -143,9 +144,9 @@ var addToCart = {
|
|
|
143
144
|
}
|
|
144
145
|
],
|
|
145
146
|
source: {
|
|
146
|
-
type: "
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
type: "browser",
|
|
148
|
+
platform: "web",
|
|
149
|
+
url: "https://shop.example.com/products/running-shoes"
|
|
149
150
|
}
|
|
150
151
|
}),
|
|
151
152
|
mapping: {
|
|
@@ -210,9 +211,9 @@ var viewItem = {
|
|
|
210
211
|
}
|
|
211
212
|
],
|
|
212
213
|
source: {
|
|
213
|
-
type: "
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
type: "browser",
|
|
215
|
+
platform: "web",
|
|
216
|
+
url: "https://shop.example.com/products/coffee-maker"
|
|
216
217
|
}
|
|
217
218
|
}),
|
|
218
219
|
mapping: {
|
|
@@ -266,9 +267,9 @@ var pageView = {
|
|
|
266
267
|
in: (0, import_core.getEvent)("page view", {
|
|
267
268
|
timestamp: 1700000903e3,
|
|
268
269
|
source: {
|
|
269
|
-
type: "
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
type: "browser",
|
|
271
|
+
platform: "web",
|
|
272
|
+
url: "https://example.com/"
|
|
272
273
|
}
|
|
273
274
|
}),
|
|
274
275
|
mapping: {
|
package/dist/examples/index.mjs
CHANGED
|
@@ -43,9 +43,10 @@ var purchase = {
|
|
|
43
43
|
],
|
|
44
44
|
user: { id: "user-123", device: "device-456" },
|
|
45
45
|
source: {
|
|
46
|
-
type: "
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
type: "browser",
|
|
47
|
+
platform: "web",
|
|
48
|
+
url: "https://shop.example.com/checkout/complete",
|
|
49
|
+
referrer: "https://shop.example.com/cart"
|
|
49
50
|
}
|
|
50
51
|
}),
|
|
51
52
|
mapping: {
|
|
@@ -122,9 +123,9 @@ var addToCart = {
|
|
|
122
123
|
}
|
|
123
124
|
],
|
|
124
125
|
source: {
|
|
125
|
-
type: "
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
type: "browser",
|
|
127
|
+
platform: "web",
|
|
128
|
+
url: "https://shop.example.com/products/running-shoes"
|
|
128
129
|
}
|
|
129
130
|
}),
|
|
130
131
|
mapping: {
|
|
@@ -189,9 +190,9 @@ var viewItem = {
|
|
|
189
190
|
}
|
|
190
191
|
],
|
|
191
192
|
source: {
|
|
192
|
-
type: "
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
type: "browser",
|
|
194
|
+
platform: "web",
|
|
195
|
+
url: "https://shop.example.com/products/coffee-maker"
|
|
195
196
|
}
|
|
196
197
|
}),
|
|
197
198
|
mapping: {
|
|
@@ -245,9 +246,9 @@ var pageView = {
|
|
|
245
246
|
in: getEvent("page view", {
|
|
246
247
|
timestamp: 1700000903e3,
|
|
247
248
|
source: {
|
|
248
|
-
type: "
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
type: "browser",
|
|
250
|
+
platform: "web",
|
|
251
|
+
url: "https://example.com/"
|
|
251
252
|
}
|
|
252
253
|
}),
|
|
253
254
|
mapping: {
|
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,{DestinationCriteo:()=>types_exports,default:()=>index_default,destinationCriteo:()=>destinationCriteo}),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 DEFAULT_URL="https://widget.criteo.com/m/event?version=s2s_v0";var import_core=require("@walkeros/core"),import_server_core2=require("@walkeros/server-core"),import_crypto=require("crypto"),import_server_core=require("@walkeros/server-core");var sha256HexPattern=/^[a-f0-9]{64}$/,md5HexPattern=/^[a-f0-9]{32}$/;async function hashEmail(email){const normalized=email.toLowerCase().trim();if(!normalized)return{};if(value=normalized,sha256HexPattern.test(value))return{sha256:normalized};var value;if(function(value){return md5HexPattern.test(value)}(normalized)){return{md5:normalized,sha256_md5:await(0,import_server_core.getHashServer)(normalized)}}const md5=function(value){return(0,import_crypto.createHash)("md5").update(value.toLowerCase().trim()).digest("hex")}(normalized);return{md5:md5,sha256:await(0,import_server_core.getHashServer)(normalized),sha256_md5:await(0,import_server_core.getHashServer)(md5)}}function toStringOrUndef(value){if(null!=value)return"string"==typeof value?value:"number"==typeof value||"boolean"==typeof value?String(value):void 0}function toNumberOrUndef(value){if("number"==typeof value&&Number.isFinite(value))return value;if("string"==typeof value&&""!==value){const n=Number(value);if(Number.isFinite(n))return n}}var push=async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){
|
|
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,{DestinationCriteo:()=>types_exports,default:()=>index_default,destinationCriteo:()=>destinationCriteo}),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 DEFAULT_URL="https://widget.criteo.com/m/event?version=s2s_v0";var import_core=require("@walkeros/core"),import_server_core2=require("@walkeros/server-core"),import_crypto=require("crypto"),import_server_core=require("@walkeros/server-core");var sha256HexPattern=/^[a-f0-9]{64}$/,md5HexPattern=/^[a-f0-9]{32}$/;async function hashEmail(email){const normalized=email.toLowerCase().trim();if(!normalized)return{};if(value=normalized,sha256HexPattern.test(value))return{sha256:normalized};var value;if(function(value){return md5HexPattern.test(value)}(normalized)){return{md5:normalized,sha256_md5:await(0,import_server_core.getHashServer)(normalized)}}const md5=function(value){return(0,import_crypto.createHash)("md5").update(value.toLowerCase().trim()).digest("hex")}(normalized);return{md5:md5,sha256:await(0,import_server_core.getHashServer)(normalized),sha256_md5:await(0,import_server_core.getHashServer)(md5)}}function toStringOrUndef(value){if(null!=value)return"string"==typeof value?value:"number"==typeof value||"boolean"==typeof value?String(value):void 0}function toNumberOrUndef(value){if("number"==typeof value&&Number.isFinite(value))return value;if("string"==typeof value&&""!==value){const n=Number(value);if(Number.isFinite(n))return n}}var push=async function(event,{config:config,rule:rule,data:data,env:env,logger:logger,collector:collector}){const{partnerId:partnerId,callerId:callerId,siteType:siteType="d",country:country,language:language,url:url=DEFAULT_URL,user_data:user_data}=config.settings,eventData=(0,import_core.isObject)(data)?data:{},userDataCustom=user_data?await(0,import_core.getMappingValue)(event,{map:user_data},{collector:collector}):{},resolvedUserData=(0,import_core.isObject)(userDataCustom)?userDataCustom:{},identity={mapping_key:callerId},mappedUserId=toStringOrUndef(resolvedUserData.mapped_user_id);mappedUserId&&(identity.mapped_user_id=mappedUserId);const rawEmail=toStringOrUndef(resolvedUserData.email);if(rawEmail){const hashes=await hashEmail(rawEmail);Object.keys(hashes).length>0&&(identity.email=hashes)}const criteoEvent={event:"string"==typeof rule?.name&&rule.name||event.name,timestamp:(ts=event.timestamp,"number"==typeof ts&&Number.isFinite(ts)?new Date(ts).toISOString():"string"==typeof ts&&ts?ts:(new Date).toISOString())};var ts;const eventId=toStringOrUndef(eventData.id);eventId&&(criteoEvent.id=eventId);const items=function(raw){if(!Array.isArray(raw))return;const items=[];for(const entry of raw){if(!(0,import_core.isObject)(entry))continue;const id=toStringOrUndef(entry.id);if(!id)continue;const item={id:id},price=toNumberOrUndef(entry.price);void 0!==price&&(item.price=price);const quantity=toNumberOrUndef(entry.quantity);void 0!==quantity&&(item.quantity=quantity),items.push(item)}return items.length?items:void 0}(eventData.item);items&&(criteoEvent.item=items);const dedupId=toStringOrUndef(eventData.deduplication_page_view_id);dedupId&&(criteoEvent.deduplication_page_view_id=dedupId);const body={version:"walkeros_criteo_1.0.0",site_type:siteType,account:partnerId,id:identity,events:[criteoEvent]};event.source?.url&&(body.full_url=event.source.url),event.source?.referrer&&(body.previous_url=event.source.referrer);const retailerVisitorId=toStringOrUndef(resolvedUserData.retailer_visitor_id);retailerVisitorId&&(body.retailer_visitor_id=retailerVisitorId);const ip=toStringOrUndef(resolvedUserData.ip);ip&&(body.ip=ip);const useragent=toStringOrUndef(resolvedUserData.useragent);useragent&&(body.useragent=useragent),country&&(body.country=country),language&&(body.language=language),logger.debug("Calling Criteo Events API",{url:url,method:"POST",eventName:criteoEvent.event,eventId:criteoEvent.id});const sendServerFn=env?.sendServer||import_server_core2.sendServer,result=await sendServerFn(url,JSON.stringify(body));logger.debug("Criteo API response",{ok:!(0,import_core.isObject)(result)||result.ok}),(0,import_core.isObject)(result)&&!1===result.ok&&logger.throw(`Criteo API error: ${JSON.stringify(result)}`)},types_exports={},destinationCriteo={type:"criteo",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{partnerId:partnerId,callerId:callerId}=settings;partnerId||logger.throw("Config settings partnerId missing"),callerId||logger.throw("Config settings callerId missing");const settingsConfig={siteType:"d",url:DEFAULT_URL,...settings,partnerId:partnerId,callerId:callerId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await push(event,context)},index_default=destinationCriteo;//# 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 DestinationCriteo from './types';\n\nexport const destinationCriteo: Destination = {\n type: 'criteo',\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 destinationCriteo;\n","import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport const DEFAULT_URL = 'https://widget.criteo.com/m/event?version=s2s_v0';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { partnerId, callerId } = settings;\n\n if (!partnerId) logger.throw('Config settings partnerId missing');\n if (!callerId) logger.throw('Config settings callerId missing');\n\n const settingsConfig: Settings = {\n siteType: 'd',\n url: DEFAULT_URL,\n ...settings,\n partnerId,\n callerId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n CriteoEvent,\n CriteoIdentity,\n CriteoItem,\n CriteoRequestBody,\n Env,\n PushFn,\n Settings,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEmail } from './hash';\nimport { DEFAULT_URL } from './config';\n\nconst INTEGRATION_VERSION = 'walkeros_criteo_1.0.0';\n\nfunction toStringOrUndef(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value);\n return undefined;\n}\n\nfunction toNumberOrUndef(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value !== '') {\n const n = Number(value);\n if (Number.isFinite(n)) return n;\n }\n return undefined;\n}\n\nfunction toIsoTimestamp(ts: unknown): string {\n if (typeof ts === 'number' && Number.isFinite(ts)) {\n return new Date(ts).toISOString();\n }\n if (typeof ts === 'string' && ts) return ts;\n return new Date().toISOString();\n}\n\nfunction toItems(raw: unknown): CriteoItem[] | undefined {\n if (!Array.isArray(raw)) return undefined;\n const items: CriteoItem[] = [];\n for (const entry of raw) {\n if (!isObject(entry)) continue;\n const id = toStringOrUndef(entry.id);\n if (!id) continue;\n const item: CriteoItem = { id };\n const price = toNumberOrUndef(entry.price);\n if (price !== undefined) item.price = price;\n const quantity = toNumberOrUndef(entry.quantity);\n if (quantity !== undefined) item.quantity = quantity;\n items.push(item);\n }\n return items.length ? items : undefined;\n}\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n partnerId,\n callerId,\n siteType = 'd',\n country,\n language,\n url = DEFAULT_URL,\n user_data,\n } = config.settings as Settings;\n\n const eventData = isObject(data) ? data : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n const resolvedUserData = isObject(userDataCustom) ? userDataCustom : {};\n\n // Build identity block\n const identity: CriteoIdentity = { mapping_key: callerId };\n\n const mappedUserId = toStringOrUndef(resolvedUserData.mapped_user_id);\n if (mappedUserId) identity.mapped_user_id = mappedUserId;\n\n const rawEmail = toStringOrUndef(resolvedUserData.email);\n if (rawEmail) {\n const hashes = await hashEmail(rawEmail);\n if (Object.keys(hashes).length > 0) identity.email = hashes;\n }\n\n // Build event object\n const criteoEventName =\n (typeof rule?.name === 'string' && rule.name) || event.name;\n\n const criteoEvent: CriteoEvent = {\n event: criteoEventName,\n timestamp: toIsoTimestamp(event.timestamp),\n };\n\n const eventId = toStringOrUndef(eventData.id);\n if (eventId) criteoEvent.id = eventId;\n\n const items = toItems(eventData.item);\n if (items) criteoEvent.item = items;\n\n const dedupId = toStringOrUndef(eventData.deduplication_page_view_id);\n if (dedupId) criteoEvent.deduplication_page_view_id = dedupId;\n\n // Build request body\n const body: CriteoRequestBody = {\n version: INTEGRATION_VERSION,\n site_type: siteType,\n account: partnerId,\n id: identity,\n events: [criteoEvent],\n };\n\n if (event.source?.id) body.full_url = event.source.id;\n if (event.source?.previous_id) body.previous_url = event.source.previous_id;\n\n const retailerVisitorId = toStringOrUndef(\n resolvedUserData.retailer_visitor_id,\n );\n if (retailerVisitorId) body.retailer_visitor_id = retailerVisitorId;\n\n const ip = toStringOrUndef(resolvedUserData.ip);\n if (ip) body.ip = ip;\n\n const useragent = toStringOrUndef(resolvedUserData.useragent);\n if (useragent) body.useragent = useragent;\n\n if (country) body.country = country;\n if (language) body.language = language;\n\n logger.debug('Calling Criteo Events API', {\n url,\n method: 'POST',\n eventName: criteoEvent.event,\n eventId: criteoEvent.id,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(url, JSON.stringify(body));\n\n logger.debug('Criteo API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Criteo API error: ${JSON.stringify(result)}`);\n }\n};\n","import { createHash } from 'crypto';\nimport { getHashServer } from '@walkeros/server-core';\nimport type { CriteoEmailHashes } from './types';\n\n/**\n * Criteo Events API expects email in three hashed forms:\n * - md5: MD5 of lowercased/trimmed email\n * - sha256: SHA-256 of lowercased/trimmed email\n * - sha256_md5: SHA-256 of the MD5 hash (hex string)\n *\n * https://guides.criteotilt.com/events-api/\n */\n\n/** MD5 hex digest of the lowercased/trimmed input */\nexport function hashMD5(value: string): string {\n return createHash('md5').update(value.toLowerCase().trim()).digest('hex');\n}\n\nconst sha256HexPattern = /^[a-f0-9]{64}$/;\nconst md5HexPattern = /^[a-f0-9]{32}$/;\n\nfunction isSha256Hex(value: string): boolean {\n return sha256HexPattern.test(value);\n}\n\nfunction isMd5Hex(value: string): boolean {\n return md5HexPattern.test(value);\n}\n\n/**\n * Hash an email address into Criteo's three expected forms.\n * If the input already looks like a SHA-256 hex string, it is not re-hashed.\n * If the input looks like an MD5 hex string, it is used directly as md5.\n */\nexport async function hashEmail(email: string): Promise<CriteoEmailHashes> {\n const normalized = email.toLowerCase().trim();\n if (!normalized) return {};\n\n // Already SHA-256 hashed — can't derive md5 from it, only pass through.\n if (isSha256Hex(normalized)) {\n return { sha256: normalized };\n }\n\n // Already MD5 hashed — derive sha256_md5 from it, can't derive sha256.\n if (isMd5Hex(normalized)) {\n const sha256_md5 = await getHashServer(normalized);\n return { md5: normalized, sha256_md5 };\n }\n\n const md5 = hashMD5(normalized);\n const sha256 = await getHashServer(normalized);\n const sha256_md5 = await getHashServer(md5);\n return { md5, sha256, sha256_md5 };\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 /** Criteo Partner ID (numeric string, provided by Criteo) */\n partnerId: string;\n /** Caller ID for user mapping (provided by Criteo) */\n callerId: string;\n /** Site type: `d` (desktop), `m` (mobile web), `t` (tablet). Default `d`. */\n siteType?: SiteType;\n /** ISO 3166-1 alpha-2 country code */\n country?: string;\n /** 2-letter language code */\n language?: string;\n /** API endpoint override (default: https://widget.criteo.com/m/event?version=s2s_v0) */\n url?: string;\n /** Mapping for identity fields (mapped_user_id, email, retailer_visitor_id) */\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\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/** Site type: desktop / mobile web / tablet */\nexport type SiteType = 'd' | 'm' | 't';\n\n/**\n * Criteo Events API (S2S v0)\n * https://guides.criteotilt.com/events-api/\n */\nexport interface CriteoRequestBody {\n /** Integration version identifier (e.g. `walkeros_criteo_1.0.0`) */\n version: string;\n site_type?: SiteType;\n /** Criteo Partner ID */\n account: string;\n id: CriteoIdentity;\n ip?: string;\n full_url?: string;\n previous_url?: string;\n useragent?: string;\n retailer_visitor_id?: string;\n country?: string;\n language?: string;\n events: CriteoEvent[];\n}\n\nexport interface CriteoIdentity {\n /** GUM ID */\n mapped_user_id?: string;\n /** Caller ID (provided by Criteo) */\n mapping_key: string;\n email?: CriteoEmailHashes;\n}\n\nexport interface CriteoEmailHashes {\n raw?: string;\n md5?: string;\n sha256?: string;\n sha256_md5?: string;\n}\n\nexport interface CriteoEvent {\n event: CriteoEventName;\n /** ISO 8601 timestamp */\n timestamp?: string;\n /** Transaction ID or event-level ID */\n id?: string;\n item?: CriteoItem[];\n deduplication_page_view_id?: string;\n}\n\nexport interface CriteoItem {\n id: string;\n price?: number;\n quantity?: number;\n}\n\n/**\n * Standard Criteo Events API event names.\n * Custom event names are also accepted as plain strings.\n */\nexport type CriteoEventName =\n | 'viewHome'\n | 'viewPage'\n | 'viewItem'\n | 'viewList'\n | 'addToCart'\n | 'viewBasket'\n | 'beginCheckout'\n | 'trackTransaction'\n | 'addPaymentInfo'\n | 'login'\n | (string & {});\n"],"mappings":"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","names":["import_server_core","sha256_md5"]}
|
|
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 DestinationCriteo from './types';\n\nexport const destinationCriteo: Destination = {\n type: 'criteo',\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 destinationCriteo;\n","import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport const DEFAULT_URL = 'https://widget.criteo.com/m/event?version=s2s_v0';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { partnerId, callerId } = settings;\n\n if (!partnerId) logger.throw('Config settings partnerId missing');\n if (!callerId) logger.throw('Config settings callerId missing');\n\n const settingsConfig: Settings = {\n siteType: 'd',\n url: DEFAULT_URL,\n ...settings,\n partnerId,\n callerId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n CriteoEvent,\n CriteoIdentity,\n CriteoItem,\n CriteoRequestBody,\n Env,\n PushFn,\n Settings,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEmail } from './hash';\nimport { DEFAULT_URL } from './config';\n\nconst INTEGRATION_VERSION = 'walkeros_criteo_1.0.0';\n\nfunction toStringOrUndef(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value);\n return undefined;\n}\n\nfunction toNumberOrUndef(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value !== '') {\n const n = Number(value);\n if (Number.isFinite(n)) return n;\n }\n return undefined;\n}\n\nfunction toIsoTimestamp(ts: unknown): string {\n if (typeof ts === 'number' && Number.isFinite(ts)) {\n return new Date(ts).toISOString();\n }\n if (typeof ts === 'string' && ts) return ts;\n return new Date().toISOString();\n}\n\nfunction toItems(raw: unknown): CriteoItem[] | undefined {\n if (!Array.isArray(raw)) return undefined;\n const items: CriteoItem[] = [];\n for (const entry of raw) {\n if (!isObject(entry)) continue;\n const id = toStringOrUndef(entry.id);\n if (!id) continue;\n const item: CriteoItem = { id };\n const price = toNumberOrUndef(entry.price);\n if (price !== undefined) item.price = price;\n const quantity = toNumberOrUndef(entry.quantity);\n if (quantity !== undefined) item.quantity = quantity;\n items.push(item);\n }\n return items.length ? items : undefined;\n}\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger, collector },\n) {\n const {\n partnerId,\n callerId,\n siteType = 'd',\n country,\n language,\n url = DEFAULT_URL,\n user_data,\n } = config.settings as Settings;\n\n const eventData = isObject(data) ? data : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data }, { collector })\n : {};\n const resolvedUserData = isObject(userDataCustom) ? userDataCustom : {};\n\n // Build identity block\n const identity: CriteoIdentity = { mapping_key: callerId };\n\n const mappedUserId = toStringOrUndef(resolvedUserData.mapped_user_id);\n if (mappedUserId) identity.mapped_user_id = mappedUserId;\n\n const rawEmail = toStringOrUndef(resolvedUserData.email);\n if (rawEmail) {\n const hashes = await hashEmail(rawEmail);\n if (Object.keys(hashes).length > 0) identity.email = hashes;\n }\n\n // Build event object\n const criteoEventName =\n (typeof rule?.name === 'string' && rule.name) || event.name;\n\n const criteoEvent: CriteoEvent = {\n event: criteoEventName,\n timestamp: toIsoTimestamp(event.timestamp),\n };\n\n const eventId = toStringOrUndef(eventData.id);\n if (eventId) criteoEvent.id = eventId;\n\n const items = toItems(eventData.item);\n if (items) criteoEvent.item = items;\n\n const dedupId = toStringOrUndef(eventData.deduplication_page_view_id);\n if (dedupId) criteoEvent.deduplication_page_view_id = dedupId;\n\n // Build request body\n const body: CriteoRequestBody = {\n version: INTEGRATION_VERSION,\n site_type: siteType,\n account: partnerId,\n id: identity,\n events: [criteoEvent],\n };\n\n if (event.source?.url) body.full_url = event.source.url;\n if (event.source?.referrer) body.previous_url = event.source.referrer;\n\n const retailerVisitorId = toStringOrUndef(\n resolvedUserData.retailer_visitor_id,\n );\n if (retailerVisitorId) body.retailer_visitor_id = retailerVisitorId;\n\n const ip = toStringOrUndef(resolvedUserData.ip);\n if (ip) body.ip = ip;\n\n const useragent = toStringOrUndef(resolvedUserData.useragent);\n if (useragent) body.useragent = useragent;\n\n if (country) body.country = country;\n if (language) body.language = language;\n\n logger.debug('Calling Criteo Events API', {\n url,\n method: 'POST',\n eventName: criteoEvent.event,\n eventId: criteoEvent.id,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(url, JSON.stringify(body));\n\n logger.debug('Criteo API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Criteo API error: ${JSON.stringify(result)}`);\n }\n};\n","import { createHash } from 'crypto';\nimport { getHashServer } from '@walkeros/server-core';\nimport type { CriteoEmailHashes } from './types';\n\n/**\n * Criteo Events API expects email in three hashed forms:\n * - md5: MD5 of lowercased/trimmed email\n * - sha256: SHA-256 of lowercased/trimmed email\n * - sha256_md5: SHA-256 of the MD5 hash (hex string)\n *\n * https://guides.criteotilt.com/events-api/\n */\n\n/** MD5 hex digest of the lowercased/trimmed input */\nexport function hashMD5(value: string): string {\n return createHash('md5').update(value.toLowerCase().trim()).digest('hex');\n}\n\nconst sha256HexPattern = /^[a-f0-9]{64}$/;\nconst md5HexPattern = /^[a-f0-9]{32}$/;\n\nfunction isSha256Hex(value: string): boolean {\n return sha256HexPattern.test(value);\n}\n\nfunction isMd5Hex(value: string): boolean {\n return md5HexPattern.test(value);\n}\n\n/**\n * Hash an email address into Criteo's three expected forms.\n * If the input already looks like a SHA-256 hex string, it is not re-hashed.\n * If the input looks like an MD5 hex string, it is used directly as md5.\n */\nexport async function hashEmail(email: string): Promise<CriteoEmailHashes> {\n const normalized = email.toLowerCase().trim();\n if (!normalized) return {};\n\n // Already SHA-256 hashed — can't derive md5 from it, only pass through.\n if (isSha256Hex(normalized)) {\n return { sha256: normalized };\n }\n\n // Already MD5 hashed — derive sha256_md5 from it, can't derive sha256.\n if (isMd5Hex(normalized)) {\n const sha256_md5 = await getHashServer(normalized);\n return { md5: normalized, sha256_md5 };\n }\n\n const md5 = hashMD5(normalized);\n const sha256 = await getHashServer(normalized);\n const sha256_md5 = await getHashServer(md5);\n return { md5, sha256, sha256_md5 };\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 /** Criteo Partner ID (numeric string, provided by Criteo) */\n partnerId: string;\n /** Caller ID for user mapping (provided by Criteo) */\n callerId: string;\n /** Site type: `d` (desktop), `m` (mobile web), `t` (tablet). Default `d`. */\n siteType?: SiteType;\n /** ISO 3166-1 alpha-2 country code */\n country?: string;\n /** 2-letter language code */\n language?: string;\n /** API endpoint override (default: https://widget.criteo.com/m/event?version=s2s_v0) */\n url?: string;\n /** Mapping for identity fields (mapped_user_id, email, retailer_visitor_id) */\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\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/** Site type: desktop / mobile web / tablet */\nexport type SiteType = 'd' | 'm' | 't';\n\n/**\n * Criteo Events API (S2S v0)\n * https://guides.criteotilt.com/events-api/\n */\nexport interface CriteoRequestBody {\n /** Integration version identifier (e.g. `walkeros_criteo_1.0.0`) */\n version: string;\n site_type?: SiteType;\n /** Criteo Partner ID */\n account: string;\n id: CriteoIdentity;\n ip?: string;\n full_url?: string;\n previous_url?: string;\n useragent?: string;\n retailer_visitor_id?: string;\n country?: string;\n language?: string;\n events: CriteoEvent[];\n}\n\nexport interface CriteoIdentity {\n /** GUM ID */\n mapped_user_id?: string;\n /** Caller ID (provided by Criteo) */\n mapping_key: string;\n email?: CriteoEmailHashes;\n}\n\nexport interface CriteoEmailHashes {\n raw?: string;\n md5?: string;\n sha256?: string;\n sha256_md5?: string;\n}\n\nexport interface CriteoEvent {\n event: CriteoEventName;\n /** ISO 8601 timestamp */\n timestamp?: string;\n /** Transaction ID or event-level ID */\n id?: string;\n item?: CriteoItem[];\n deduplication_page_view_id?: string;\n}\n\nexport interface CriteoItem {\n id: string;\n price?: number;\n quantity?: number;\n}\n\n/**\n * Standard Criteo Events API event names.\n * Custom event names are also accepted as plain strings.\n */\nexport type CriteoEventName =\n | 'viewHome'\n | 'viewPage'\n | 'viewItem'\n | 'viewList'\n | 'addToCart'\n | 'viewBasket'\n | 'beginCheckout'\n | 'trackTransaction'\n | 'addPaymentInfo'\n | 'login'\n | (string & {});\n"],"mappings":"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","names":["import_server_core","sha256_md5"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var DEFAULT_URL="https://widget.criteo.com/m/event?version=s2s_v0";import{getMappingValue,isObject}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{createHash}from"crypto";import{getHashServer}from"@walkeros/server-core";var sha256HexPattern=/^[a-f0-9]{64}$/,md5HexPattern=/^[a-f0-9]{32}$/;async function hashEmail(email){const normalized=email.toLowerCase().trim();if(!normalized)return{};if(value=normalized,sha256HexPattern.test(value))return{sha256:normalized};var value;if(function(value){return md5HexPattern.test(value)}(normalized)){return{md5:normalized,sha256_md5:await getHashServer(normalized)}}const md5=function(value){return createHash("md5").update(value.toLowerCase().trim()).digest("hex")}(normalized);return{md5:md5,sha256:await getHashServer(normalized),sha256_md5:await getHashServer(md5)}}function toStringOrUndef(value){if(null!=value)return"string"==typeof value?value:"number"==typeof value||"boolean"==typeof value?String(value):void 0}function toNumberOrUndef(value){if("number"==typeof value&&Number.isFinite(value))return value;if("string"==typeof value&&""!==value){const n=Number(value);if(Number.isFinite(n))return n}}var push=async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){
|
|
1
|
+
var DEFAULT_URL="https://widget.criteo.com/m/event?version=s2s_v0";import{getMappingValue,isObject}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{createHash}from"crypto";import{getHashServer}from"@walkeros/server-core";var sha256HexPattern=/^[a-f0-9]{64}$/,md5HexPattern=/^[a-f0-9]{32}$/;async function hashEmail(email){const normalized=email.toLowerCase().trim();if(!normalized)return{};if(value=normalized,sha256HexPattern.test(value))return{sha256:normalized};var value;if(function(value){return md5HexPattern.test(value)}(normalized)){return{md5:normalized,sha256_md5:await getHashServer(normalized)}}const md5=function(value){return createHash("md5").update(value.toLowerCase().trim()).digest("hex")}(normalized);return{md5:md5,sha256:await getHashServer(normalized),sha256_md5:await getHashServer(md5)}}function toStringOrUndef(value){if(null!=value)return"string"==typeof value?value:"number"==typeof value||"boolean"==typeof value?String(value):void 0}function toNumberOrUndef(value){if("number"==typeof value&&Number.isFinite(value))return value;if("string"==typeof value&&""!==value){const n=Number(value);if(Number.isFinite(n))return n}}var push=async function(event,{config:config,rule:rule,data:data,env:env,logger:logger,collector:collector}){const{partnerId:partnerId,callerId:callerId,siteType:siteType="d",country:country,language:language,url:url=DEFAULT_URL,user_data:user_data}=config.settings,eventData=isObject(data)?data:{},userDataCustom=user_data?await getMappingValue(event,{map:user_data},{collector:collector}):{},resolvedUserData=isObject(userDataCustom)?userDataCustom:{},identity={mapping_key:callerId},mappedUserId=toStringOrUndef(resolvedUserData.mapped_user_id);mappedUserId&&(identity.mapped_user_id=mappedUserId);const rawEmail=toStringOrUndef(resolvedUserData.email);if(rawEmail){const hashes=await hashEmail(rawEmail);Object.keys(hashes).length>0&&(identity.email=hashes)}const criteoEvent={event:"string"==typeof rule?.name&&rule.name||event.name,timestamp:(ts=event.timestamp,"number"==typeof ts&&Number.isFinite(ts)?new Date(ts).toISOString():"string"==typeof ts&&ts?ts:(new Date).toISOString())};var ts;const eventId=toStringOrUndef(eventData.id);eventId&&(criteoEvent.id=eventId);const items=function(raw){if(!Array.isArray(raw))return;const items=[];for(const entry of raw){if(!isObject(entry))continue;const id=toStringOrUndef(entry.id);if(!id)continue;const item={id:id},price=toNumberOrUndef(entry.price);void 0!==price&&(item.price=price);const quantity=toNumberOrUndef(entry.quantity);void 0!==quantity&&(item.quantity=quantity),items.push(item)}return items.length?items:void 0}(eventData.item);items&&(criteoEvent.item=items);const dedupId=toStringOrUndef(eventData.deduplication_page_view_id);dedupId&&(criteoEvent.deduplication_page_view_id=dedupId);const body={version:"walkeros_criteo_1.0.0",site_type:siteType,account:partnerId,id:identity,events:[criteoEvent]};event.source?.url&&(body.full_url=event.source.url),event.source?.referrer&&(body.previous_url=event.source.referrer);const retailerVisitorId=toStringOrUndef(resolvedUserData.retailer_visitor_id);retailerVisitorId&&(body.retailer_visitor_id=retailerVisitorId);const ip=toStringOrUndef(resolvedUserData.ip);ip&&(body.ip=ip);const useragent=toStringOrUndef(resolvedUserData.useragent);useragent&&(body.useragent=useragent),country&&(body.country=country),language&&(body.language=language),logger.debug("Calling Criteo Events API",{url:url,method:"POST",eventName:criteoEvent.event,eventId:criteoEvent.id});const sendServerFn=env?.sendServer||sendServer,result=await sendServerFn(url,JSON.stringify(body));logger.debug("Criteo API response",{ok:!isObject(result)||result.ok}),isObject(result)&&!1===result.ok&&logger.throw(`Criteo API error: ${JSON.stringify(result)}`)},types_exports={},destinationCriteo={type:"criteo",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{partnerId:partnerId,callerId:callerId}=settings;partnerId||logger.throw("Config settings partnerId missing"),callerId||logger.throw("Config settings callerId missing");const settingsConfig={siteType:"d",url:DEFAULT_URL,...settings,partnerId:partnerId,callerId:callerId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await push(event,context)},index_default=destinationCriteo;export{types_exports as DestinationCriteo,index_default as default,destinationCriteo};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -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 const DEFAULT_URL = 'https://widget.criteo.com/m/event?version=s2s_v0';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { partnerId, callerId } = settings;\n\n if (!partnerId) logger.throw('Config settings partnerId missing');\n if (!callerId) logger.throw('Config settings callerId missing');\n\n const settingsConfig: Settings = {\n siteType: 'd',\n url: DEFAULT_URL,\n ...settings,\n partnerId,\n callerId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n CriteoEvent,\n CriteoIdentity,\n CriteoItem,\n CriteoRequestBody,\n Env,\n PushFn,\n Settings,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEmail } from './hash';\nimport { DEFAULT_URL } from './config';\n\nconst INTEGRATION_VERSION = 'walkeros_criteo_1.0.0';\n\nfunction toStringOrUndef(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value);\n return undefined;\n}\n\nfunction toNumberOrUndef(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value !== '') {\n const n = Number(value);\n if (Number.isFinite(n)) return n;\n }\n return undefined;\n}\n\nfunction toIsoTimestamp(ts: unknown): string {\n if (typeof ts === 'number' && Number.isFinite(ts)) {\n return new Date(ts).toISOString();\n }\n if (typeof ts === 'string' && ts) return ts;\n return new Date().toISOString();\n}\n\nfunction toItems(raw: unknown): CriteoItem[] | undefined {\n if (!Array.isArray(raw)) return undefined;\n const items: CriteoItem[] = [];\n for (const entry of raw) {\n if (!isObject(entry)) continue;\n const id = toStringOrUndef(entry.id);\n if (!id) continue;\n const item: CriteoItem = { id };\n const price = toNumberOrUndef(entry.price);\n if (price !== undefined) item.price = price;\n const quantity = toNumberOrUndef(entry.quantity);\n if (quantity !== undefined) item.quantity = quantity;\n items.push(item);\n }\n return items.length ? items : undefined;\n}\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n partnerId,\n callerId,\n siteType = 'd',\n country,\n language,\n url = DEFAULT_URL,\n user_data,\n } = config.settings as Settings;\n\n const eventData = isObject(data) ? data : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n const resolvedUserData = isObject(userDataCustom) ? userDataCustom : {};\n\n // Build identity block\n const identity: CriteoIdentity = { mapping_key: callerId };\n\n const mappedUserId = toStringOrUndef(resolvedUserData.mapped_user_id);\n if (mappedUserId) identity.mapped_user_id = mappedUserId;\n\n const rawEmail = toStringOrUndef(resolvedUserData.email);\n if (rawEmail) {\n const hashes = await hashEmail(rawEmail);\n if (Object.keys(hashes).length > 0) identity.email = hashes;\n }\n\n // Build event object\n const criteoEventName =\n (typeof rule?.name === 'string' && rule.name) || event.name;\n\n const criteoEvent: CriteoEvent = {\n event: criteoEventName,\n timestamp: toIsoTimestamp(event.timestamp),\n };\n\n const eventId = toStringOrUndef(eventData.id);\n if (eventId) criteoEvent.id = eventId;\n\n const items = toItems(eventData.item);\n if (items) criteoEvent.item = items;\n\n const dedupId = toStringOrUndef(eventData.deduplication_page_view_id);\n if (dedupId) criteoEvent.deduplication_page_view_id = dedupId;\n\n // Build request body\n const body: CriteoRequestBody = {\n version: INTEGRATION_VERSION,\n site_type: siteType,\n account: partnerId,\n id: identity,\n events: [criteoEvent],\n };\n\n if (event.source?.id) body.full_url = event.source.id;\n if (event.source?.previous_id) body.previous_url = event.source.previous_id;\n\n const retailerVisitorId = toStringOrUndef(\n resolvedUserData.retailer_visitor_id,\n );\n if (retailerVisitorId) body.retailer_visitor_id = retailerVisitorId;\n\n const ip = toStringOrUndef(resolvedUserData.ip);\n if (ip) body.ip = ip;\n\n const useragent = toStringOrUndef(resolvedUserData.useragent);\n if (useragent) body.useragent = useragent;\n\n if (country) body.country = country;\n if (language) body.language = language;\n\n logger.debug('Calling Criteo Events API', {\n url,\n method: 'POST',\n eventName: criteoEvent.event,\n eventId: criteoEvent.id,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(url, JSON.stringify(body));\n\n logger.debug('Criteo API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Criteo API error: ${JSON.stringify(result)}`);\n }\n};\n","import { createHash } from 'crypto';\nimport { getHashServer } from '@walkeros/server-core';\nimport type { CriteoEmailHashes } from './types';\n\n/**\n * Criteo Events API expects email in three hashed forms:\n * - md5: MD5 of lowercased/trimmed email\n * - sha256: SHA-256 of lowercased/trimmed email\n * - sha256_md5: SHA-256 of the MD5 hash (hex string)\n *\n * https://guides.criteotilt.com/events-api/\n */\n\n/** MD5 hex digest of the lowercased/trimmed input */\nexport function hashMD5(value: string): string {\n return createHash('md5').update(value.toLowerCase().trim()).digest('hex');\n}\n\nconst sha256HexPattern = /^[a-f0-9]{64}$/;\nconst md5HexPattern = /^[a-f0-9]{32}$/;\n\nfunction isSha256Hex(value: string): boolean {\n return sha256HexPattern.test(value);\n}\n\nfunction isMd5Hex(value: string): boolean {\n return md5HexPattern.test(value);\n}\n\n/**\n * Hash an email address into Criteo's three expected forms.\n * If the input already looks like a SHA-256 hex string, it is not re-hashed.\n * If the input looks like an MD5 hex string, it is used directly as md5.\n */\nexport async function hashEmail(email: string): Promise<CriteoEmailHashes> {\n const normalized = email.toLowerCase().trim();\n if (!normalized) return {};\n\n // Already SHA-256 hashed — can't derive md5 from it, only pass through.\n if (isSha256Hex(normalized)) {\n return { sha256: normalized };\n }\n\n // Already MD5 hashed — derive sha256_md5 from it, can't derive sha256.\n if (isMd5Hex(normalized)) {\n const sha256_md5 = await getHashServer(normalized);\n return { md5: normalized, sha256_md5 };\n }\n\n const md5 = hashMD5(normalized);\n const sha256 = await getHashServer(normalized);\n const sha256_md5 = await getHashServer(md5);\n return { md5, sha256, sha256_md5 };\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 /** Criteo Partner ID (numeric string, provided by Criteo) */\n partnerId: string;\n /** Caller ID for user mapping (provided by Criteo) */\n callerId: string;\n /** Site type: `d` (desktop), `m` (mobile web), `t` (tablet). Default `d`. */\n siteType?: SiteType;\n /** ISO 3166-1 alpha-2 country code */\n country?: string;\n /** 2-letter language code */\n language?: string;\n /** API endpoint override (default: https://widget.criteo.com/m/event?version=s2s_v0) */\n url?: string;\n /** Mapping for identity fields (mapped_user_id, email, retailer_visitor_id) */\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\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/** Site type: desktop / mobile web / tablet */\nexport type SiteType = 'd' | 'm' | 't';\n\n/**\n * Criteo Events API (S2S v0)\n * https://guides.criteotilt.com/events-api/\n */\nexport interface CriteoRequestBody {\n /** Integration version identifier (e.g. `walkeros_criteo_1.0.0`) */\n version: string;\n site_type?: SiteType;\n /** Criteo Partner ID */\n account: string;\n id: CriteoIdentity;\n ip?: string;\n full_url?: string;\n previous_url?: string;\n useragent?: string;\n retailer_visitor_id?: string;\n country?: string;\n language?: string;\n events: CriteoEvent[];\n}\n\nexport interface CriteoIdentity {\n /** GUM ID */\n mapped_user_id?: string;\n /** Caller ID (provided by Criteo) */\n mapping_key: string;\n email?: CriteoEmailHashes;\n}\n\nexport interface CriteoEmailHashes {\n raw?: string;\n md5?: string;\n sha256?: string;\n sha256_md5?: string;\n}\n\nexport interface CriteoEvent {\n event: CriteoEventName;\n /** ISO 8601 timestamp */\n timestamp?: string;\n /** Transaction ID or event-level ID */\n id?: string;\n item?: CriteoItem[];\n deduplication_page_view_id?: string;\n}\n\nexport interface CriteoItem {\n id: string;\n price?: number;\n quantity?: number;\n}\n\n/**\n * Standard Criteo Events API event names.\n * Custom event names are also accepted as plain strings.\n */\nexport type CriteoEventName =\n | 'viewHome'\n | 'viewPage'\n | 'viewItem'\n | 'viewList'\n | 'addToCart'\n | 'viewBasket'\n | 'beginCheckout'\n | 'trackTransaction'\n | 'addPaymentInfo'\n | 'login'\n | (string & {});\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationCriteo from './types';\n\nexport const destinationCriteo: Destination = {\n type: 'criteo',\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 destinationCriteo;\n"],"mappings":"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","names":["sha256_md5"]}
|
|
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 const DEFAULT_URL = 'https://widget.criteo.com/m/event?version=s2s_v0';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { partnerId, callerId } = settings;\n\n if (!partnerId) logger.throw('Config settings partnerId missing');\n if (!callerId) logger.throw('Config settings callerId missing');\n\n const settingsConfig: Settings = {\n siteType: 'd',\n url: DEFAULT_URL,\n ...settings,\n partnerId,\n callerId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n CriteoEvent,\n CriteoIdentity,\n CriteoItem,\n CriteoRequestBody,\n Env,\n PushFn,\n Settings,\n} from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEmail } from './hash';\nimport { DEFAULT_URL } from './config';\n\nconst INTEGRATION_VERSION = 'walkeros_criteo_1.0.0';\n\nfunction toStringOrUndef(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value);\n return undefined;\n}\n\nfunction toNumberOrUndef(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value !== '') {\n const n = Number(value);\n if (Number.isFinite(n)) return n;\n }\n return undefined;\n}\n\nfunction toIsoTimestamp(ts: unknown): string {\n if (typeof ts === 'number' && Number.isFinite(ts)) {\n return new Date(ts).toISOString();\n }\n if (typeof ts === 'string' && ts) return ts;\n return new Date().toISOString();\n}\n\nfunction toItems(raw: unknown): CriteoItem[] | undefined {\n if (!Array.isArray(raw)) return undefined;\n const items: CriteoItem[] = [];\n for (const entry of raw) {\n if (!isObject(entry)) continue;\n const id = toStringOrUndef(entry.id);\n if (!id) continue;\n const item: CriteoItem = { id };\n const price = toNumberOrUndef(entry.price);\n if (price !== undefined) item.price = price;\n const quantity = toNumberOrUndef(entry.quantity);\n if (quantity !== undefined) item.quantity = quantity;\n items.push(item);\n }\n return items.length ? items : undefined;\n}\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger, collector },\n) {\n const {\n partnerId,\n callerId,\n siteType = 'd',\n country,\n language,\n url = DEFAULT_URL,\n user_data,\n } = config.settings as Settings;\n\n const eventData = isObject(data) ? data : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data }, { collector })\n : {};\n const resolvedUserData = isObject(userDataCustom) ? userDataCustom : {};\n\n // Build identity block\n const identity: CriteoIdentity = { mapping_key: callerId };\n\n const mappedUserId = toStringOrUndef(resolvedUserData.mapped_user_id);\n if (mappedUserId) identity.mapped_user_id = mappedUserId;\n\n const rawEmail = toStringOrUndef(resolvedUserData.email);\n if (rawEmail) {\n const hashes = await hashEmail(rawEmail);\n if (Object.keys(hashes).length > 0) identity.email = hashes;\n }\n\n // Build event object\n const criteoEventName =\n (typeof rule?.name === 'string' && rule.name) || event.name;\n\n const criteoEvent: CriteoEvent = {\n event: criteoEventName,\n timestamp: toIsoTimestamp(event.timestamp),\n };\n\n const eventId = toStringOrUndef(eventData.id);\n if (eventId) criteoEvent.id = eventId;\n\n const items = toItems(eventData.item);\n if (items) criteoEvent.item = items;\n\n const dedupId = toStringOrUndef(eventData.deduplication_page_view_id);\n if (dedupId) criteoEvent.deduplication_page_view_id = dedupId;\n\n // Build request body\n const body: CriteoRequestBody = {\n version: INTEGRATION_VERSION,\n site_type: siteType,\n account: partnerId,\n id: identity,\n events: [criteoEvent],\n };\n\n if (event.source?.url) body.full_url = event.source.url;\n if (event.source?.referrer) body.previous_url = event.source.referrer;\n\n const retailerVisitorId = toStringOrUndef(\n resolvedUserData.retailer_visitor_id,\n );\n if (retailerVisitorId) body.retailer_visitor_id = retailerVisitorId;\n\n const ip = toStringOrUndef(resolvedUserData.ip);\n if (ip) body.ip = ip;\n\n const useragent = toStringOrUndef(resolvedUserData.useragent);\n if (useragent) body.useragent = useragent;\n\n if (country) body.country = country;\n if (language) body.language = language;\n\n logger.debug('Calling Criteo Events API', {\n url,\n method: 'POST',\n eventName: criteoEvent.event,\n eventId: criteoEvent.id,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(url, JSON.stringify(body));\n\n logger.debug('Criteo API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Criteo API error: ${JSON.stringify(result)}`);\n }\n};\n","import { createHash } from 'crypto';\nimport { getHashServer } from '@walkeros/server-core';\nimport type { CriteoEmailHashes } from './types';\n\n/**\n * Criteo Events API expects email in three hashed forms:\n * - md5: MD5 of lowercased/trimmed email\n * - sha256: SHA-256 of lowercased/trimmed email\n * - sha256_md5: SHA-256 of the MD5 hash (hex string)\n *\n * https://guides.criteotilt.com/events-api/\n */\n\n/** MD5 hex digest of the lowercased/trimmed input */\nexport function hashMD5(value: string): string {\n return createHash('md5').update(value.toLowerCase().trim()).digest('hex');\n}\n\nconst sha256HexPattern = /^[a-f0-9]{64}$/;\nconst md5HexPattern = /^[a-f0-9]{32}$/;\n\nfunction isSha256Hex(value: string): boolean {\n return sha256HexPattern.test(value);\n}\n\nfunction isMd5Hex(value: string): boolean {\n return md5HexPattern.test(value);\n}\n\n/**\n * Hash an email address into Criteo's three expected forms.\n * If the input already looks like a SHA-256 hex string, it is not re-hashed.\n * If the input looks like an MD5 hex string, it is used directly as md5.\n */\nexport async function hashEmail(email: string): Promise<CriteoEmailHashes> {\n const normalized = email.toLowerCase().trim();\n if (!normalized) return {};\n\n // Already SHA-256 hashed — can't derive md5 from it, only pass through.\n if (isSha256Hex(normalized)) {\n return { sha256: normalized };\n }\n\n // Already MD5 hashed — derive sha256_md5 from it, can't derive sha256.\n if (isMd5Hex(normalized)) {\n const sha256_md5 = await getHashServer(normalized);\n return { md5: normalized, sha256_md5 };\n }\n\n const md5 = hashMD5(normalized);\n const sha256 = await getHashServer(normalized);\n const sha256_md5 = await getHashServer(md5);\n return { md5, sha256, sha256_md5 };\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 /** Criteo Partner ID (numeric string, provided by Criteo) */\n partnerId: string;\n /** Caller ID for user mapping (provided by Criteo) */\n callerId: string;\n /** Site type: `d` (desktop), `m` (mobile web), `t` (tablet). Default `d`. */\n siteType?: SiteType;\n /** ISO 3166-1 alpha-2 country code */\n country?: string;\n /** 2-letter language code */\n language?: string;\n /** API endpoint override (default: https://widget.criteo.com/m/event?version=s2s_v0) */\n url?: string;\n /** Mapping for identity fields (mapped_user_id, email, retailer_visitor_id) */\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\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/** Site type: desktop / mobile web / tablet */\nexport type SiteType = 'd' | 'm' | 't';\n\n/**\n * Criteo Events API (S2S v0)\n * https://guides.criteotilt.com/events-api/\n */\nexport interface CriteoRequestBody {\n /** Integration version identifier (e.g. `walkeros_criteo_1.0.0`) */\n version: string;\n site_type?: SiteType;\n /** Criteo Partner ID */\n account: string;\n id: CriteoIdentity;\n ip?: string;\n full_url?: string;\n previous_url?: string;\n useragent?: string;\n retailer_visitor_id?: string;\n country?: string;\n language?: string;\n events: CriteoEvent[];\n}\n\nexport interface CriteoIdentity {\n /** GUM ID */\n mapped_user_id?: string;\n /** Caller ID (provided by Criteo) */\n mapping_key: string;\n email?: CriteoEmailHashes;\n}\n\nexport interface CriteoEmailHashes {\n raw?: string;\n md5?: string;\n sha256?: string;\n sha256_md5?: string;\n}\n\nexport interface CriteoEvent {\n event: CriteoEventName;\n /** ISO 8601 timestamp */\n timestamp?: string;\n /** Transaction ID or event-level ID */\n id?: string;\n item?: CriteoItem[];\n deduplication_page_view_id?: string;\n}\n\nexport interface CriteoItem {\n id: string;\n price?: number;\n quantity?: number;\n}\n\n/**\n * Standard Criteo Events API event names.\n * Custom event names are also accepted as plain strings.\n */\nexport type CriteoEventName =\n | 'viewHome'\n | 'viewPage'\n | 'viewItem'\n | 'viewList'\n | 'addToCart'\n | 'viewBasket'\n | 'beginCheckout'\n | 'trackTransaction'\n | 'addPaymentInfo'\n | 'login'\n | (string & {});\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationCriteo from './types';\n\nexport const destinationCriteo: Destination = {\n type: 'criteo',\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 destinationCriteo;\n"],"mappings":"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","names":["sha256_md5"]}
|
package/dist/walkerOS.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$meta": {
|
|
3
3
|
"package": "@walkeros/server-destination-criteo",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0-next-1777882869103",
|
|
5
5
|
"type": "destination",
|
|
6
6
|
"platform": [
|
|
7
7
|
"server"
|
|
@@ -127,22 +127,16 @@
|
|
|
127
127
|
"consent": {
|
|
128
128
|
"functional": true
|
|
129
129
|
},
|
|
130
|
-
"id": "
|
|
130
|
+
"id": "1f37553ee528f6f4",
|
|
131
131
|
"trigger": "click",
|
|
132
132
|
"entity": "product",
|
|
133
133
|
"action": "add",
|
|
134
134
|
"timestamp": 1700000901000,
|
|
135
135
|
"timing": 3.14,
|
|
136
|
-
"group": "gr0up",
|
|
137
|
-
"count": 1,
|
|
138
|
-
"version": {
|
|
139
|
-
"source": "3.4.2",
|
|
140
|
-
"tagging": 1
|
|
141
|
-
},
|
|
142
136
|
"source": {
|
|
143
|
-
"type": "
|
|
144
|
-
"
|
|
145
|
-
"
|
|
137
|
+
"type": "browser",
|
|
138
|
+
"platform": "web",
|
|
139
|
+
"url": "https://shop.example.com/products/running-shoes"
|
|
146
140
|
}
|
|
147
141
|
},
|
|
148
142
|
"mapping": {
|
|
@@ -154,7 +148,7 @@
|
|
|
154
148
|
"nested",
|
|
155
149
|
{
|
|
156
150
|
"condition": {
|
|
157
|
-
"$code": "e=>
|
|
151
|
+
"$code": "e=>w(e)&&\"product\"===e.entity"
|
|
158
152
|
},
|
|
159
153
|
"map": {
|
|
160
154
|
"id": "data.id",
|
|
@@ -213,35 +207,22 @@
|
|
|
213
207
|
"entity": "child",
|
|
214
208
|
"data": {
|
|
215
209
|
"is": "subordinated"
|
|
216
|
-
},
|
|
217
|
-
"nested": [],
|
|
218
|
-
"context": {
|
|
219
|
-
"element": [
|
|
220
|
-
"child",
|
|
221
|
-
0
|
|
222
|
-
]
|
|
223
210
|
}
|
|
224
211
|
}
|
|
225
212
|
],
|
|
226
213
|
"consent": {
|
|
227
214
|
"functional": true
|
|
228
215
|
},
|
|
229
|
-
"id": "
|
|
216
|
+
"id": "05cd28f431d2e585",
|
|
230
217
|
"trigger": "load",
|
|
231
218
|
"entity": "page",
|
|
232
219
|
"action": "view",
|
|
233
220
|
"timestamp": 1700000903000,
|
|
234
221
|
"timing": 3.14,
|
|
235
|
-
"group": "gr0up",
|
|
236
|
-
"count": 1,
|
|
237
|
-
"version": {
|
|
238
|
-
"source": "3.4.2",
|
|
239
|
-
"tagging": 1
|
|
240
|
-
},
|
|
241
222
|
"source": {
|
|
242
|
-
"type": "
|
|
243
|
-
"
|
|
244
|
-
"
|
|
223
|
+
"type": "browser",
|
|
224
|
+
"platform": "web",
|
|
225
|
+
"url": "https://example.com/"
|
|
245
226
|
}
|
|
246
227
|
},
|
|
247
228
|
"mapping": {
|
|
@@ -295,22 +276,17 @@
|
|
|
295
276
|
"consent": {
|
|
296
277
|
"functional": true
|
|
297
278
|
},
|
|
298
|
-
"id": "
|
|
279
|
+
"id": "701f26beeb17b08c",
|
|
299
280
|
"trigger": "load",
|
|
300
281
|
"entity": "order",
|
|
301
282
|
"action": "complete",
|
|
302
283
|
"timestamp": 1700000900000,
|
|
303
284
|
"timing": 3.14,
|
|
304
|
-
"group": "gr0up",
|
|
305
|
-
"count": 1,
|
|
306
|
-
"version": {
|
|
307
|
-
"source": "3.4.2",
|
|
308
|
-
"tagging": 1
|
|
309
|
-
},
|
|
310
285
|
"source": {
|
|
311
|
-
"type": "
|
|
312
|
-
"
|
|
313
|
-
"
|
|
286
|
+
"type": "browser",
|
|
287
|
+
"platform": "web",
|
|
288
|
+
"url": "https://shop.example.com/checkout/complete",
|
|
289
|
+
"referrer": "https://shop.example.com/cart"
|
|
314
290
|
}
|
|
315
291
|
},
|
|
316
292
|
"mapping": {
|
|
@@ -323,7 +299,7 @@
|
|
|
323
299
|
"nested",
|
|
324
300
|
{
|
|
325
301
|
"condition": {
|
|
326
|
-
"$code": "e=>
|
|
302
|
+
"$code": "e=>w(e)&&\"product\"===e.entity"
|
|
327
303
|
},
|
|
328
304
|
"map": {
|
|
329
305
|
"id": "data.id",
|
|
@@ -384,22 +360,16 @@
|
|
|
384
360
|
"consent": {
|
|
385
361
|
"functional": true
|
|
386
362
|
},
|
|
387
|
-
"id": "
|
|
363
|
+
"id": "99f3ef46f02a9eec",
|
|
388
364
|
"trigger": "load",
|
|
389
365
|
"entity": "product",
|
|
390
366
|
"action": "view",
|
|
391
367
|
"timestamp": 1700000902000,
|
|
392
368
|
"timing": 3.14,
|
|
393
|
-
"group": "gr0up",
|
|
394
|
-
"count": 1,
|
|
395
|
-
"version": {
|
|
396
|
-
"source": "3.4.2",
|
|
397
|
-
"tagging": 1
|
|
398
|
-
},
|
|
399
369
|
"source": {
|
|
400
|
-
"type": "
|
|
401
|
-
"
|
|
402
|
-
"
|
|
370
|
+
"type": "browser",
|
|
371
|
+
"platform": "web",
|
|
372
|
+
"url": "https://shop.example.com/products/coffee-maker"
|
|
403
373
|
}
|
|
404
374
|
},
|
|
405
375
|
"mapping": {
|
|
@@ -411,7 +381,7 @@
|
|
|
411
381
|
"nested",
|
|
412
382
|
{
|
|
413
383
|
"condition": {
|
|
414
|
-
"$code": "e=>
|
|
384
|
+
"$code": "e=>w(e)&&\"product\"===e.entity"
|
|
415
385
|
},
|
|
416
386
|
"map": {
|
|
417
387
|
"id": "data.id"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/server-destination-criteo",
|
|
3
3
|
"description": "Criteo Events API server destination for walkerOS",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0-next-1777882869103",
|
|
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": "
|
|
38
|
-
"@walkeros/server-core": "
|
|
37
|
+
"@walkeros/core": "4.0.0-next-1777882869103",
|
|
38
|
+
"@walkeros/server-core": "4.0.0-next-1777882869103"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@walkeros/collector": "
|
|
41
|
+
"@walkeros/collector": "4.0.0-next-1777882869103"
|
|
42
42
|
},
|
|
43
43
|
"repository": {
|
|
44
44
|
"url": "git+https://github.com/elbwalker/walkerOS.git",
|