@walkeros/web-source-datalayer 2.2.0-next-1773136823705 → 3.0.0
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.d.mts +5 -1
- package/dist/dev.d.ts +5 -1
- 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.d.mts +5 -1
- package/dist/examples/index.d.ts +5 -1
- package/dist/examples/index.js +75 -1
- package/dist/examples/index.mjs +75 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.es5.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +76 -2
- package/package.json +5 -5
package/dist/dev.d.mts
CHANGED
|
@@ -55,13 +55,17 @@ declare namespace env {
|
|
|
55
55
|
|
|
56
56
|
declare const gtagPurchase: Flow.StepExample;
|
|
57
57
|
declare const consentUpdate: Flow.StepExample;
|
|
58
|
+
declare const gtagAddToCart: Flow.StepExample;
|
|
59
|
+
declare const gtagViewItem: Flow.StepExample;
|
|
58
60
|
declare const directEvent: Flow.StepExample;
|
|
59
61
|
|
|
60
62
|
declare const step_consentUpdate: typeof consentUpdate;
|
|
61
63
|
declare const step_directEvent: typeof directEvent;
|
|
64
|
+
declare const step_gtagAddToCart: typeof gtagAddToCart;
|
|
62
65
|
declare const step_gtagPurchase: typeof gtagPurchase;
|
|
66
|
+
declare const step_gtagViewItem: typeof gtagViewItem;
|
|
63
67
|
declare namespace step {
|
|
64
|
-
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagPurchase as gtagPurchase };
|
|
68
|
+
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagAddToCart as gtagAddToCart, step_gtagPurchase as gtagPurchase, step_gtagViewItem as gtagViewItem };
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
/** Prepopulates window.dataLayer before source init. */
|
package/dist/dev.d.ts
CHANGED
|
@@ -55,13 +55,17 @@ declare namespace env {
|
|
|
55
55
|
|
|
56
56
|
declare const gtagPurchase: Flow.StepExample;
|
|
57
57
|
declare const consentUpdate: Flow.StepExample;
|
|
58
|
+
declare const gtagAddToCart: Flow.StepExample;
|
|
59
|
+
declare const gtagViewItem: Flow.StepExample;
|
|
58
60
|
declare const directEvent: Flow.StepExample;
|
|
59
61
|
|
|
60
62
|
declare const step_consentUpdate: typeof consentUpdate;
|
|
61
63
|
declare const step_directEvent: typeof directEvent;
|
|
64
|
+
declare const step_gtagAddToCart: typeof gtagAddToCart;
|
|
62
65
|
declare const step_gtagPurchase: typeof gtagPurchase;
|
|
66
|
+
declare const step_gtagViewItem: typeof gtagViewItem;
|
|
63
67
|
declare namespace step {
|
|
64
|
-
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagPurchase as gtagPurchase };
|
|
68
|
+
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagAddToCart as gtagAddToCart, step_gtagPurchase as gtagPurchase, step_gtagViewItem as gtagViewItem };
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
/** Prepopulates window.dataLayer before source init. */
|
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,i=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},o={};i(o,{examples:()=>_,schemas:()=>d}),module.exports=(e=o,((e,i,o,d)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let c of r(i))n.call(e,c)||c===o||t(e,c,{get:()=>i[c],enumerable:!(d=a(i,c))||d.enumerable});return e})(t({},"__esModule",{value:!0}),e));var d={};i(d,{EventPrefix:()=>y,JavaScriptVarName:()=>u,SettingsSchema:()=>v,settings:()=>l});var c=require("@walkeros/core/dev"),s=require("@walkeros/core/dev"),m=require("@walkeros/core/dev"),u=m.z.string().min(1).regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/,"Must be a valid JavaScript identifier").describe("JavaScript variable name"),y=m.z.string().min(1).describe("Prefix for filtering dataLayer events"),v=s.z.object({name:u.default("dataLayer").describe("DataLayer variable name (default: dataLayer)").optional(),prefix:y.default("dataLayer").describe("Event prefix for filtering which events to process").optional(),filter:s.z.any().describe("Custom filter function: (event: unknown) => boolean | Promise<boolean>").optional()}),l=(0,c.zodToSchema)(v),_={};i(_,{env:()=>p,setup:()=>j,step:()=>L});var p={};i(p,{push:()=>w});var g=()=>{},f=()=>()=>Promise.resolve({ok:!0}),b={error:g,warn:g,info:g,debug:g,throw:e=>{throw"string"==typeof e?new Error(e):e},json:g,scope:()=>b},w={get push(){return f()},get command(){return f()},get elb(){return f()},get window(){return{dataLayer:[],addEventListener:g,removeEventListener:g}},logger:b},L={};i(L,{consentUpdate:()=>S,directEvent:()=>P,gtagAddToCart:()=>U,gtagPurchase:()=>h,gtagViewItem:()=>E});var h={in:["event","purchase",{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]}],out:{name:"dataLayer purchase",data:{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]},entity:"dataLayer",action:"purchase"}},S={in:["consent","update",{ad_storage:"granted",analytics_storage:"granted"}],out:{name:"dataLayer consent update",data:{ad_storage:"granted",analytics_storage:"granted"},entity:"dataLayer",action:"consent update"}},U={in:["event","add_to_cart",{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]}],out:{name:"dataLayer add_to_cart",data:{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]},entity:"dataLayer",action:"add_to_cart"}},E={in:["event","view_item",{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]}],out:{name:"dataLayer view_item",data:{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]},entity:"dataLayer",action:"view_item"}},P={in:{event:"custom_event",category:"engagement",label:"video_play"},out:{name:"dataLayer custom_event",data:{category:"engagement",label:"video_play"},entity:"dataLayer",action:"custom_event"}},j=(e,t)=>{const a=t.window;if(a.dataLayer||(a.dataLayer=[]),Array.isArray(e))for(const t of e)a.dataLayer.push(t);else e&&"object"==typeof e&&a.dataLayer.push(e)};//# 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/primitives.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/setup.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\nimport { JavaScriptVarName, EventPrefix } from './primitives';\n\n/**\n * DataLayer source settings schema\n */\nexport const SettingsSchema = z.object({\n name: JavaScriptVarName.default('dataLayer')\n .describe('DataLayer variable name (default: dataLayer)')\n .optional(),\n\n prefix: EventPrefix.default('dataLayer')\n .describe('Event prefix for filtering which events to process')\n .optional(),\n\n filter: z\n .any()\n .describe(\n 'Custom filter function: (event: unknown) => boolean | Promise<boolean>',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * JavaScript variable name\n * Used for dataLayer variable naming\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * Event prefix\n * Used for filtering dataLayer events\n */\nexport const EventPrefix = z\n .string()\n .min(1)\n .describe('Prefix for filtering dataLayer events');\n","export * as env from './env';\nexport * as step from './step';\nexport { setup } from './setup';\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n entity: 'dataLayer',\n action: 'purchase',\n },\n};\n\nexport const consentUpdate: Flow.StepExample = {\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n entity: 'dataLayer',\n action: 'consent update',\n },\n};\n\nexport const directEvent: Flow.StepExample = {\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n entity: 'dataLayer',\n action: 'custom_event',\n },\n};\n","import type { Source } from '@walkeros/core';\n\n/** Prepopulates window.dataLayer before source init. */\nexport const setup: Source.SetupFn = (input, env) => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n\n if (Array.isArray(input)) {\n for (const item of input) win.dataLayer.push(item);\n } else if (input && typeof input === 'object') {\n win.dataLayer.push(input);\n }\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
|
|
1
|
+
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/setup.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\nimport { JavaScriptVarName, EventPrefix } from './primitives';\n\n/**\n * DataLayer source settings schema\n */\nexport const SettingsSchema = z.object({\n name: JavaScriptVarName.default('dataLayer')\n .describe('DataLayer variable name (default: dataLayer)')\n .optional(),\n\n prefix: EventPrefix.default('dataLayer')\n .describe('Event prefix for filtering which events to process')\n .optional(),\n\n filter: z\n .any()\n .describe(\n 'Custom filter function: (event: unknown) => boolean | Promise<boolean>',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * JavaScript variable name\n * Used for dataLayer variable naming\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * Event prefix\n * Used for filtering dataLayer events\n */\nexport const EventPrefix = z\n .string()\n .min(1)\n .describe('Prefix for filtering dataLayer events');\n","export * as env from './env';\nexport * as step from './step';\nexport { setup } from './setup';\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n entity: 'dataLayer',\n action: 'purchase',\n },\n};\n\nexport const consentUpdate: Flow.StepExample = {\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n entity: 'dataLayer',\n action: 'consent update',\n },\n};\n\nexport const gtagAddToCart: Flow.StepExample = {\n in: [\n 'event',\n 'add_to_cart',\n {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n ],\n out: {\n name: 'dataLayer add_to_cart',\n data: {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n entity: 'dataLayer',\n action: 'add_to_cart',\n },\n};\n\nexport const gtagViewItem: Flow.StepExample = {\n in: [\n 'event',\n 'view_item',\n {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n ],\n out: {\n name: 'dataLayer view_item',\n data: {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n entity: 'dataLayer',\n action: 'view_item',\n },\n};\n\nexport const directEvent: Flow.StepExample = {\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n entity: 'dataLayer',\n action: 'custom_event',\n },\n};\n","import type { Source } from '@walkeros/core';\n\n/** Prepopulates window.dataLayer before source init. */\nexport const setup: Source.SetupFn = (input, env) => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n\n if (Array.isArray(input)) {\n for (const item of input) win.dataLayer.push(item);\n } else if (input && typeof input === 'object') {\n win.dataLayer.push(input);\n }\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,a=(a,t)=>{for(var r in t)e(a,r,{get:t[r],enumerable:!0})},t={};a(t,{EventPrefix:()=>
|
|
1
|
+
var e=Object.defineProperty,a=(a,t)=>{for(var r in t)e(a,r,{get:t[r],enumerable:!0})},t={};a(t,{EventPrefix:()=>d,JavaScriptVarName:()=>o,SettingsSchema:()=>s,settings:()=>c});import{zodToSchema as r}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";import{z as n}from"@walkeros/core/dev";var o=n.string().min(1).regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/,"Must be a valid JavaScript identifier").describe("JavaScript variable name"),d=n.string().min(1).describe("Prefix for filtering dataLayer events"),s=i.object({name:o.default("dataLayer").describe("DataLayer variable name (default: dataLayer)").optional(),prefix:d.default("dataLayer").describe("Event prefix for filtering which events to process").optional(),filter:i.any().describe("Custom filter function: (event: unknown) => boolean | Promise<boolean>").optional()}),c=r(s),m={};a(m,{env:()=>u,setup:()=>h,step:()=>l});var u={};a(u,{push:()=>g});var y=()=>{},v=()=>()=>Promise.resolve({ok:!0}),_={error:y,warn:y,info:y,debug:y,throw:e=>{throw"string"==typeof e?new Error(e):e},json:y,scope:()=>_},g={get push(){return v()},get command(){return v()},get elb(){return v()},get window(){return{dataLayer:[],addEventListener:y,removeEventListener:y}},logger:_},l={};a(l,{consentUpdate:()=>f,directEvent:()=>b,gtagAddToCart:()=>L,gtagPurchase:()=>p,gtagViewItem:()=>w});var p={in:["event","purchase",{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]}],out:{name:"dataLayer purchase",data:{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]},entity:"dataLayer",action:"purchase"}},f={in:["consent","update",{ad_storage:"granted",analytics_storage:"granted"}],out:{name:"dataLayer consent update",data:{ad_storage:"granted",analytics_storage:"granted"},entity:"dataLayer",action:"consent update"}},L={in:["event","add_to_cart",{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]}],out:{name:"dataLayer add_to_cart",data:{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]},entity:"dataLayer",action:"add_to_cart"}},w={in:["event","view_item",{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]}],out:{name:"dataLayer view_item",data:{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]},entity:"dataLayer",action:"view_item"}},b={in:{event:"custom_event",category:"engagement",label:"video_play"},out:{name:"dataLayer custom_event",data:{category:"engagement",label:"video_play"},entity:"dataLayer",action:"custom_event"}},h=(e,a)=>{const t=a.window;if(t.dataLayer||(t.dataLayer=[]),Array.isArray(e))for(const a of e)t.dataLayer.push(a);else e&&"object"==typeof e&&t.dataLayer.push(e)};export{m as examples,t 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/primitives.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/setup.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\nimport { JavaScriptVarName, EventPrefix } from './primitives';\n\n/**\n * DataLayer source settings schema\n */\nexport const SettingsSchema = z.object({\n name: JavaScriptVarName.default('dataLayer')\n .describe('DataLayer variable name (default: dataLayer)')\n .optional(),\n\n prefix: EventPrefix.default('dataLayer')\n .describe('Event prefix for filtering which events to process')\n .optional(),\n\n filter: z\n .any()\n .describe(\n 'Custom filter function: (event: unknown) => boolean | Promise<boolean>',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * JavaScript variable name\n * Used for dataLayer variable naming\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * Event prefix\n * Used for filtering dataLayer events\n */\nexport const EventPrefix = z\n .string()\n .min(1)\n .describe('Prefix for filtering dataLayer events');\n","export * as env from './env';\nexport * as step from './step';\nexport { setup } from './setup';\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n entity: 'dataLayer',\n action: 'purchase',\n },\n};\n\nexport const consentUpdate: Flow.StepExample = {\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n entity: 'dataLayer',\n action: 'consent update',\n },\n};\n\nexport const directEvent: Flow.StepExample = {\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n entity: 'dataLayer',\n action: 'custom_event',\n },\n};\n","import type { Source } from '@walkeros/core';\n\n/** Prepopulates window.dataLayer before source init. */\nexport const setup: Source.SetupFn = (input, env) => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n\n if (Array.isArray(input)) {\n for (const item of input) win.dataLayer.push(item);\n } else if (input && typeof input === 'object') {\n win.dataLayer.push(input);\n }\n};\n"],"mappings":"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","names":["z","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/setup.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\nimport { JavaScriptVarName, EventPrefix } from './primitives';\n\n/**\n * DataLayer source settings schema\n */\nexport const SettingsSchema = z.object({\n name: JavaScriptVarName.default('dataLayer')\n .describe('DataLayer variable name (default: dataLayer)')\n .optional(),\n\n prefix: EventPrefix.default('dataLayer')\n .describe('Event prefix for filtering which events to process')\n .optional(),\n\n filter: z\n .any()\n .describe(\n 'Custom filter function: (event: unknown) => boolean | Promise<boolean>',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * JavaScript variable name\n * Used for dataLayer variable naming\n */\nexport const JavaScriptVarName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/, 'Must be a valid JavaScript identifier')\n .describe('JavaScript variable name');\n\n/**\n * Event prefix\n * Used for filtering dataLayer events\n */\nexport const EventPrefix = z\n .string()\n .min(1)\n .describe('Prefix for filtering dataLayer events');\n","export * as env from './env';\nexport * as step from './step';\nexport { setup } from './setup';\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n entity: 'dataLayer',\n action: 'purchase',\n },\n};\n\nexport const consentUpdate: Flow.StepExample = {\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n entity: 'dataLayer',\n action: 'consent update',\n },\n};\n\nexport const gtagAddToCart: Flow.StepExample = {\n in: [\n 'event',\n 'add_to_cart',\n {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n ],\n out: {\n name: 'dataLayer add_to_cart',\n data: {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n entity: 'dataLayer',\n action: 'add_to_cart',\n },\n};\n\nexport const gtagViewItem: Flow.StepExample = {\n in: [\n 'event',\n 'view_item',\n {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n ],\n out: {\n name: 'dataLayer view_item',\n data: {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n entity: 'dataLayer',\n action: 'view_item',\n },\n};\n\nexport const directEvent: Flow.StepExample = {\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n entity: 'dataLayer',\n action: 'custom_event',\n },\n};\n","import type { Source } from '@walkeros/core';\n\n/** Prepopulates window.dataLayer before source init. */\nexport const setup: Source.SetupFn = (input, env) => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n\n if (Array.isArray(input)) {\n for (const item of input) win.dataLayer.push(item);\n } else if (input && typeof input === 'object') {\n win.dataLayer.push(input);\n }\n};\n"],"mappings":"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","names":["z","z"]}
|
|
@@ -21,13 +21,17 @@ declare namespace env {
|
|
|
21
21
|
|
|
22
22
|
declare const gtagPurchase: Flow.StepExample;
|
|
23
23
|
declare const consentUpdate: Flow.StepExample;
|
|
24
|
+
declare const gtagAddToCart: Flow.StepExample;
|
|
25
|
+
declare const gtagViewItem: Flow.StepExample;
|
|
24
26
|
declare const directEvent: Flow.StepExample;
|
|
25
27
|
|
|
26
28
|
declare const step_consentUpdate: typeof consentUpdate;
|
|
27
29
|
declare const step_directEvent: typeof directEvent;
|
|
30
|
+
declare const step_gtagAddToCart: typeof gtagAddToCart;
|
|
28
31
|
declare const step_gtagPurchase: typeof gtagPurchase;
|
|
32
|
+
declare const step_gtagViewItem: typeof gtagViewItem;
|
|
29
33
|
declare namespace step {
|
|
30
|
-
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagPurchase as gtagPurchase };
|
|
34
|
+
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagAddToCart as gtagAddToCart, step_gtagPurchase as gtagPurchase, step_gtagViewItem as gtagViewItem };
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
/** Prepopulates window.dataLayer before source init. */
|
package/dist/examples/index.d.ts
CHANGED
|
@@ -21,13 +21,17 @@ declare namespace env {
|
|
|
21
21
|
|
|
22
22
|
declare const gtagPurchase: Flow.StepExample;
|
|
23
23
|
declare const consentUpdate: Flow.StepExample;
|
|
24
|
+
declare const gtagAddToCart: Flow.StepExample;
|
|
25
|
+
declare const gtagViewItem: Flow.StepExample;
|
|
24
26
|
declare const directEvent: Flow.StepExample;
|
|
25
27
|
|
|
26
28
|
declare const step_consentUpdate: typeof consentUpdate;
|
|
27
29
|
declare const step_directEvent: typeof directEvent;
|
|
30
|
+
declare const step_gtagAddToCart: typeof gtagAddToCart;
|
|
28
31
|
declare const step_gtagPurchase: typeof gtagPurchase;
|
|
32
|
+
declare const step_gtagViewItem: typeof gtagViewItem;
|
|
29
33
|
declare namespace step {
|
|
30
|
-
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagPurchase as gtagPurchase };
|
|
34
|
+
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagAddToCart as gtagAddToCart, step_gtagPurchase as gtagPurchase, step_gtagViewItem as gtagViewItem };
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
/** Prepopulates window.dataLayer before source init. */
|
package/dist/examples/index.js
CHANGED
|
@@ -76,7 +76,9 @@ var step_exports = {};
|
|
|
76
76
|
__export(step_exports, {
|
|
77
77
|
consentUpdate: () => consentUpdate,
|
|
78
78
|
directEvent: () => directEvent,
|
|
79
|
-
|
|
79
|
+
gtagAddToCart: () => gtagAddToCart,
|
|
80
|
+
gtagPurchase: () => gtagPurchase,
|
|
81
|
+
gtagViewItem: () => gtagViewItem
|
|
80
82
|
});
|
|
81
83
|
var gtagPurchase = {
|
|
82
84
|
in: [
|
|
@@ -120,6 +122,78 @@ var consentUpdate = {
|
|
|
120
122
|
action: "consent update"
|
|
121
123
|
}
|
|
122
124
|
};
|
|
125
|
+
var gtagAddToCart = {
|
|
126
|
+
in: [
|
|
127
|
+
"event",
|
|
128
|
+
"add_to_cart",
|
|
129
|
+
{
|
|
130
|
+
currency: "EUR",
|
|
131
|
+
value: 15.25,
|
|
132
|
+
items: [
|
|
133
|
+
{
|
|
134
|
+
item_id: "SKU_12345",
|
|
135
|
+
item_name: "T-Shirt",
|
|
136
|
+
item_variant: "red",
|
|
137
|
+
quantity: 1,
|
|
138
|
+
price: 15.25
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
],
|
|
143
|
+
out: {
|
|
144
|
+
name: "dataLayer add_to_cart",
|
|
145
|
+
data: {
|
|
146
|
+
currency: "EUR",
|
|
147
|
+
value: 15.25,
|
|
148
|
+
items: [
|
|
149
|
+
{
|
|
150
|
+
item_id: "SKU_12345",
|
|
151
|
+
item_name: "T-Shirt",
|
|
152
|
+
item_variant: "red",
|
|
153
|
+
quantity: 1,
|
|
154
|
+
price: 15.25
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
},
|
|
158
|
+
entity: "dataLayer",
|
|
159
|
+
action: "add_to_cart"
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
var gtagViewItem = {
|
|
163
|
+
in: [
|
|
164
|
+
"event",
|
|
165
|
+
"view_item",
|
|
166
|
+
{
|
|
167
|
+
currency: "EUR",
|
|
168
|
+
value: 29.99,
|
|
169
|
+
items: [
|
|
170
|
+
{
|
|
171
|
+
item_id: "SKU_67890",
|
|
172
|
+
item_name: "Sneakers",
|
|
173
|
+
item_category: "Footwear",
|
|
174
|
+
price: 29.99
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
out: {
|
|
180
|
+
name: "dataLayer view_item",
|
|
181
|
+
data: {
|
|
182
|
+
currency: "EUR",
|
|
183
|
+
value: 29.99,
|
|
184
|
+
items: [
|
|
185
|
+
{
|
|
186
|
+
item_id: "SKU_67890",
|
|
187
|
+
item_name: "Sneakers",
|
|
188
|
+
item_category: "Footwear",
|
|
189
|
+
price: 29.99
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
entity: "dataLayer",
|
|
194
|
+
action: "view_item"
|
|
195
|
+
}
|
|
196
|
+
};
|
|
123
197
|
var directEvent = {
|
|
124
198
|
in: {
|
|
125
199
|
event: "custom_event",
|
package/dist/examples/index.mjs
CHANGED
|
@@ -54,7 +54,9 @@ var step_exports = {};
|
|
|
54
54
|
__export(step_exports, {
|
|
55
55
|
consentUpdate: () => consentUpdate,
|
|
56
56
|
directEvent: () => directEvent,
|
|
57
|
-
|
|
57
|
+
gtagAddToCart: () => gtagAddToCart,
|
|
58
|
+
gtagPurchase: () => gtagPurchase,
|
|
59
|
+
gtagViewItem: () => gtagViewItem
|
|
58
60
|
});
|
|
59
61
|
var gtagPurchase = {
|
|
60
62
|
in: [
|
|
@@ -98,6 +100,78 @@ var consentUpdate = {
|
|
|
98
100
|
action: "consent update"
|
|
99
101
|
}
|
|
100
102
|
};
|
|
103
|
+
var gtagAddToCart = {
|
|
104
|
+
in: [
|
|
105
|
+
"event",
|
|
106
|
+
"add_to_cart",
|
|
107
|
+
{
|
|
108
|
+
currency: "EUR",
|
|
109
|
+
value: 15.25,
|
|
110
|
+
items: [
|
|
111
|
+
{
|
|
112
|
+
item_id: "SKU_12345",
|
|
113
|
+
item_name: "T-Shirt",
|
|
114
|
+
item_variant: "red",
|
|
115
|
+
quantity: 1,
|
|
116
|
+
price: 15.25
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
out: {
|
|
122
|
+
name: "dataLayer add_to_cart",
|
|
123
|
+
data: {
|
|
124
|
+
currency: "EUR",
|
|
125
|
+
value: 15.25,
|
|
126
|
+
items: [
|
|
127
|
+
{
|
|
128
|
+
item_id: "SKU_12345",
|
|
129
|
+
item_name: "T-Shirt",
|
|
130
|
+
item_variant: "red",
|
|
131
|
+
quantity: 1,
|
|
132
|
+
price: 15.25
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
entity: "dataLayer",
|
|
137
|
+
action: "add_to_cart"
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
var gtagViewItem = {
|
|
141
|
+
in: [
|
|
142
|
+
"event",
|
|
143
|
+
"view_item",
|
|
144
|
+
{
|
|
145
|
+
currency: "EUR",
|
|
146
|
+
value: 29.99,
|
|
147
|
+
items: [
|
|
148
|
+
{
|
|
149
|
+
item_id: "SKU_67890",
|
|
150
|
+
item_name: "Sneakers",
|
|
151
|
+
item_category: "Footwear",
|
|
152
|
+
price: 29.99
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
out: {
|
|
158
|
+
name: "dataLayer view_item",
|
|
159
|
+
data: {
|
|
160
|
+
currency: "EUR",
|
|
161
|
+
value: 29.99,
|
|
162
|
+
items: [
|
|
163
|
+
{
|
|
164
|
+
item_id: "SKU_67890",
|
|
165
|
+
item_name: "Sneakers",
|
|
166
|
+
item_category: "Footwear",
|
|
167
|
+
price: 29.99
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
},
|
|
171
|
+
entity: "dataLayer",
|
|
172
|
+
action: "view_item"
|
|
173
|
+
}
|
|
174
|
+
};
|
|
101
175
|
var directEvent = {
|
|
102
176
|
in: {
|
|
103
177
|
event: "custom_event",
|
package/dist/index.browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var Destination=(()=>{var e=Object.defineProperty,t=Object.getOwnPropertyDescriptor,
|
|
1
|
+
"use strict";var Destination=(()=>{var e=Object.defineProperty,t=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,n=(t,r)=>{for(var a in r)e(t,a,{get:r[a],enumerable:!0})},i={};n(i,{SourceDataLayer:()=>p,default:()=>k,env:()=>_,setup:()=>T,sourceDataLayer:()=>$,step:()=>A});var o=Object.defineProperty;((e,t)=>{for(var r in t)o(e,r,{get:t[r],enumerable:!0})})({},{Level:()=>c});var u,c=((u=c||{})[u.ERROR=0]="ERROR",u[u.WARN=1]="WARN",u[u.INFO=2]="INFO",u[u.DEBUG=3]="DEBUG",u);function s(e){return Array.isArray(e)}function l(e){return"object"==typeof e&&null!==e&&!s(e)&&"[object Object]"===Object.prototype.toString.call(e)}function y(e){return"string"==typeof e}function d(e,t,r){return function(...a){try{return e(...a)}catch(e){if(!t)return;return t(e)}finally{null==r||r()}}}var f=!1;function m(e,t,r,a=globalThis.window){const n=t.settings,i=a[(null==n?void 0:n.name)||"dataLayer"];if(Array.isArray(i)&&!f){f=!0;try{const t=null!=r?r:i.length;for(let r=0;r<t;r++)g(e,n,i[r])}finally{f=!1}}}function g(e,t={},r){if(t.filter){if(!0===d(()=>t.filter(r),()=>!1)())return}const a=function(e){if(l(e)&&y(e.event)){const{event:t,...r}=e;return{name:t,...r}}if(s(e)&&e.length>=2)return v(e);if(t=e,null!=t&&"object"==typeof t&&"length"in t&&"number"==typeof t.length&&t.length>0){return v(Array.from(e))}var t;return null}(r);if(!a)return;const n=`${t.prefix||"dataLayer"} ${a.name}`,{name:i,...o}=a,u={name:n,data:o};d(()=>e(u),()=>{})()}function v(e){const[t,r,a]=e;if(!y(t))return null;let n,i={};switch(t){case"consent":if(!y(r)||e.length<3)return null;if("default"!==r&&"update"!==r)return null;if(!l(a)||null===a)return null;n=`${t} ${r}`,i={...a};break;case"event":if(!y(r))return null;n=r,l(a)&&(i={...a});break;case"config":if(!y(r))return null;n=`${t} ${r}`,l(a)&&(i={...a});break;case"set":if(y(r))n=`${t} ${r}`,l(a)&&(i={...a});else{if(!l(r))return null;n=`${t} custom`,i={...r}}break;default:return null}return{name:n,...i}}var p={},_={};n(_,{push:()=>w});var b=()=>{},h=()=>()=>Promise.resolve({ok:!0}),L={error:b,warn:b,info:b,debug:b,throw:e=>{throw"string"==typeof e?new Error(e):e},json:b,scope:()=>L},w={get push(){return h()},get command(){return h()},get elb(){return h()},get window(){return{dataLayer:[],addEventListener:b,removeEventListener:b}},logger:L},A={};n(A,{consentUpdate:()=>O,directEvent:()=>j,gtagAddToCart:()=>R,gtagPurchase:()=>E,gtagViewItem:()=>S});var U,E={in:["event","purchase",{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]}],out:{name:"dataLayer purchase",data:{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]},entity:"dataLayer",action:"purchase"}},O={in:["consent","update",{ad_storage:"granted",analytics_storage:"granted"}],out:{name:"dataLayer consent update",data:{ad_storage:"granted",analytics_storage:"granted"},entity:"dataLayer",action:"consent update"}},R={in:["event","add_to_cart",{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]}],out:{name:"dataLayer add_to_cart",data:{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]},entity:"dataLayer",action:"add_to_cart"}},S={in:["event","view_item",{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]}],out:{name:"dataLayer view_item",data:{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]},entity:"dataLayer",action:"view_item"}},j={in:{event:"custom_event",category:"engagement",label:"video_play"},out:{name:"dataLayer custom_event",data:{category:"engagement",label:"video_play"},entity:"dataLayer",action:"custom_event"}},T=(e,t)=>{const r=t.window;if(r.dataLayer||(r.dataLayer=[]),Array.isArray(e))for(const t of e)r.dataLayer.push(t);else e&&"object"==typeof e&&r.dataLayer.push(e)},$=async e=>{const{config:t,env:r}=e,{elb:a,window:n}=r,i={name:"dataLayer",prefix:"dataLayer",...null==t?void 0:t.settings},o={settings:i};let u=0;if(n){const t=i.name||"dataLayer",r=n[t];u=Array.isArray(r)?r.length:0;const c=n;!function(e,t,r=globalThis.window){const a=t.settings,n=(null==a?void 0:a.name)||"dataLayer";r[n]||(r[n]=[]);const i=r[n];if(!Array.isArray(i))return;const o=i.push.bind(i);i.push=function(...t){if(f)return o(...t);f=!0;try{for(const r of t)g(e,a,r)}finally{f=!1}return o(...t)}}(a,o,c),e.collector.allowed&&u>0&&(m(a,o,u,c),u=0)}return{type:"dataLayer",config:o,push:a,on:async e=>{if("run"===e&&n&&u>0){m(a,o,u,n),u=0}},destroy:async()=>{const e=i.name||"dataLayer";n&&n[e]&&Array.isArray(n[e])}}},k=$;return U=i,((n,i,o,u)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let c of r(i))a.call(n,c)||c===o||e(n,c,{get:()=>i[c],enumerable:!(u=t(i,c))||u.enumerable});return n})(e({},"__esModule",{value:!0}),U)})();
|
package/dist/index.d.mts
CHANGED
|
@@ -81,13 +81,17 @@ declare namespace env {
|
|
|
81
81
|
|
|
82
82
|
declare const gtagPurchase: Flow.StepExample;
|
|
83
83
|
declare const consentUpdate: Flow.StepExample;
|
|
84
|
+
declare const gtagAddToCart: Flow.StepExample;
|
|
85
|
+
declare const gtagViewItem: Flow.StepExample;
|
|
84
86
|
declare const directEvent: Flow.StepExample;
|
|
85
87
|
|
|
86
88
|
declare const step_consentUpdate: typeof consentUpdate;
|
|
87
89
|
declare const step_directEvent: typeof directEvent;
|
|
90
|
+
declare const step_gtagAddToCart: typeof gtagAddToCart;
|
|
88
91
|
declare const step_gtagPurchase: typeof gtagPurchase;
|
|
92
|
+
declare const step_gtagViewItem: typeof gtagViewItem;
|
|
89
93
|
declare namespace step {
|
|
90
|
-
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagPurchase as gtagPurchase };
|
|
94
|
+
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagAddToCart as gtagAddToCart, step_gtagPurchase as gtagPurchase, step_gtagViewItem as gtagViewItem };
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
/** Prepopulates window.dataLayer before source init. */
|
package/dist/index.d.ts
CHANGED
|
@@ -81,13 +81,17 @@ declare namespace env {
|
|
|
81
81
|
|
|
82
82
|
declare const gtagPurchase: Flow.StepExample;
|
|
83
83
|
declare const consentUpdate: Flow.StepExample;
|
|
84
|
+
declare const gtagAddToCart: Flow.StepExample;
|
|
85
|
+
declare const gtagViewItem: Flow.StepExample;
|
|
84
86
|
declare const directEvent: Flow.StepExample;
|
|
85
87
|
|
|
86
88
|
declare const step_consentUpdate: typeof consentUpdate;
|
|
87
89
|
declare const step_directEvent: typeof directEvent;
|
|
90
|
+
declare const step_gtagAddToCart: typeof gtagAddToCart;
|
|
88
91
|
declare const step_gtagPurchase: typeof gtagPurchase;
|
|
92
|
+
declare const step_gtagViewItem: typeof gtagViewItem;
|
|
89
93
|
declare namespace step {
|
|
90
|
-
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagPurchase as gtagPurchase };
|
|
94
|
+
export { step_consentUpdate as consentUpdate, step_directEvent as directEvent, step_gtagAddToCart as gtagAddToCart, step_gtagPurchase as gtagPurchase, step_gtagViewItem as gtagViewItem };
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
/** Prepopulates window.dataLayer before source init. */
|
package/dist/index.es5.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";function _array_like_to_array(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function _array_with_holes(e){if(Array.isArray(e))return e}function _array_without_holes(e){if(Array.isArray(e))return _array_like_to_array(e)}function asyncGeneratorStep(e,t,r,n,a,o,i){try{var u=e[o](i),l=u.value}catch(e){return void r(e)}u.done?t(l):Promise.resolve(l).then(n,a)}function _async_to_generator(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var o=e.apply(t,r);function i(e){asyncGeneratorStep(o,n,a,i,u,"next",e)}function u(e){asyncGeneratorStep(o,n,a,i,u,"throw",e)}i(void 0)})}}function _define_property(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function _iterable_to_array(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _iterable_to_array_limit(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,o=[],i=!0,u=!1;try{for(r=r.call(e);!(i=(n=r.next()).done)&&(o.push(n.value),!t||o.length!==t);i=!0);}catch(e){u=!0,a=e}finally{try{i||null==r.return||r.return()}finally{if(u)throw a}}return o}}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _object_spread(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),n.forEach(function(t){_define_property(e,t,r[t])})}return e}function _object_without_properties(e,t){if(null==e)return{};var r,n,a,o={};if("undefined"!=typeof Reflect&&Reflect.ownKeys){for(r=Reflect.ownKeys(Object(e)),a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n]);return o}if(o=_object_without_properties_loose(e,t),Object.getOwnPropertySymbols)for(r=Object.getOwnPropertySymbols(e),a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n]);return o}function _object_without_properties_loose(e,t){if(null==e)return{};var r,n,a={},o=Object.getOwnPropertyNames(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r]);return a}function _sliced_to_array(e,t){return _array_with_holes(e)||_iterable_to_array_limit(e,t)||_unsupported_iterable_to_array(e,t)||_non_iterable_rest()}function _to_consumable_array(e){return _array_without_holes(e)||_iterable_to_array(e)||_unsupported_iterable_to_array(e)||_non_iterable_spread()}function _type_of(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e}function _unsupported_iterable_to_array(e,t){if(e){if("string"==typeof e)return _array_like_to_array(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(r):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_array_like_to_array(e,t):void 0}}function _ts_generator(e,t){var r,n,a,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(i,"next",{value:l(0)}),u(i,"throw",{value:l(1)}),u(i,"return",{value:l(2)}),"function"==typeof Symbol&&u(i,Symbol.iterator,{value:function(){return this}}),i;function l(u){return function(l){return function(u){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,u[0]&&(o=0)),o;)try{if(r=1,n&&(a=2&u[0]?n.return:u[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,u[1])).done)return a;switch(n=0,a&&(u=[2&u[0],a.value]),u[0]){case 0:case 1:a=u;break;case 4:return o.label++,{value:u[1],done:!1};case 5:o.label++,n=u[1],u=[0];continue;case 7:u=o.ops.pop(),o.trys.pop();continue;default:if(!(a=o.trys,(a=a.length>0&&a[a.length-1])||6!==u[0]&&2!==u[0])){o=0;continue}if(3===u[0]&&(!a||u[1]>a[0]&&u[1]<a[3])){o.label=u[1];break}if(6===u[0]&&o.label<a[1]){o.label=a[1],a=u;break}if(a&&o.label<a[2]){o.label=a[2],o.ops.push(u);break}a[2]&&o.ops.pop(),o.trys.pop();continue}u=t.call(e,o)}catch(e){u=[6,e],n=0}finally{r=a=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,l])}}}var Destination=function(){var e=function(e){return Array.isArray(e)},t=function(t){return"object"==(void 0===t?"undefined":_type_of(t))&&null!==t&&!e(t)&&"[object Object]"===Object.prototype.toString.call(t)},r=function(e){return"string"==typeof e},n=function(e,t,r){return function(){for(var n=arguments.length,a=new Array(n),o=0;o<n;o++)a[o]=arguments[o];try{return e.apply(void 0,_to_consumable_array(a))}catch(e){if(!t)return;return t(e)}finally{null==r||r()}}},a=function(e,t,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:globalThis.window,a=t.settings,i=n[(null==a?void 0:a.name)||"dataLayer"];if(Array.isArray(i)&&!h){h=!0;try{for(var u=null!=r?r:i.length,l=0;l<u;l++)o(e,a,i[l])}finally{h=!1}}},o=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2?arguments[2]:void 0;if(t.filter&&!0===n(function(){return t.filter(r)},function(){return!1})())return;var a=i(r);if(a){var o=t.prefix||"dataLayer",u="".concat(o," ").concat(a.name),l=(a.name,{name:u,data:_object_without_properties(a,["name"])});n(function(){return e(l)},function(){})()}},i=function(n){if(t(n)&&r(n.event))return _object_spread({name:n.event},_object_without_properties(n,["event"]));if(e(n)&&n.length>=2)return u(n);if(l(n)){var a=Array.from(n);return u(a)}return null},u=function(e){var n,a=_sliced_to_array(e,3),o=a[0],i=a[1],u=a[2];if(!r(o))return null;var l={};switch(o){case"consent":if(!r(i)||e.length<3)return null;if("default"!==i&&"update"!==i)return null;if(!t(u)||null===u)return null;n="".concat(o," ").concat(i),l=_object_spread({},u);break;case"event":if(!r(i))return null;n=i,t(u)&&(l=_object_spread({},u));break;case"config":if(!r(i))return null;n="".concat(o," ").concat(i),t(u)&&(l=_object_spread({},u));break;case"set":if(r(i))n="".concat(o," ").concat(i),t(u)&&(l=_object_spread({},u));else{if(!t(i))return null;n="".concat(o," custom"),l=_object_spread({},i)}break;default:return null}return _object_spread({name:n},l)},l=function(e){return null!=e&&"object"===(void 0===e?"undefined":_type_of(e))&&"length"in e&&"number"==typeof e.length&&e.length>0},c=Object.defineProperty,f=Object.getOwnPropertyDescriptor,y=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,_=function(e,t){for(var r in t)c(e,r,{get:t[r],enumerable:!0})},p={};_(p,{SourceDataLayer:function(){return m},default:function(){return I},env:function(){return g},setup:function(){return x},sourceDataLayer:function(){return R},step:function(){return A}});var d=Object.defineProperty;!function(e,t){for(var r in t)d(e,r,{get:t[r],enumerable:!0})}({},{Level:function(){return v}});var b,v=((b=v||{})[b.ERROR=0]="ERROR",b[b.WARN=1]="WARN",b[b.INFO=2]="INFO",b[b.DEBUG=3]="DEBUG",b),h=!1,m={},g={};_(g,{push:function(){return S}});var w=function(){},j=function(){return function(){return Promise.resolve({ok:!0})}},O={error:w,warn:w,info:w,debug:w,throw:function(e){throw"string"==typeof e?new Error(e):e},json:w,scope:function(){return O}},S={get push(){return j()},get command(){return j()},get elb(){return j()},get window(){return{dataLayer:[],addEventListener:w,removeEventListener:w}},logger:O},A={};_(A,{consentUpdate:function(){return P},directEvent:function(){return k},gtagPurchase:function(){return E}});var L,E={in:["event","purchase",{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]}],out:{name:"dataLayer purchase",data:{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]},entity:"dataLayer",action:"purchase"}},P={in:["consent","update",{ad_storage:"granted",analytics_storage:"granted"}],out:{name:"dataLayer consent update",data:{ad_storage:"granted",analytics_storage:"granted"},entity:"dataLayer",action:"consent update"}},k={in:{event:"custom_event",category:"engagement",label:"video_play"},out:{name:"dataLayer custom_event",data:{category:"engagement",label:"video_play"},entity:"dataLayer",action:"custom_event"}},x=function(e,t){var r=t.window;if(r.dataLayer||(r.dataLayer=[]),Array.isArray(e)){var n=!0,a=!1,o=void 0;try{for(var i,u=e[Symbol.iterator]();!(n=(i=u.next()).done);n=!0){var l=i.value;r.dataLayer.push(l)}}catch(e){a=!0,o=e}finally{try{n||null==u.return||u.return()}finally{if(a)throw o}}}else e&&"object"===(void 0===e?"undefined":_type_of(e))&&r.dataLayer.push(e)},R=function(e){return _async_to_generator(function(){var t,r,n,i,u,l,c,f,y,s;return _ts_generator(this,function(_){return t=e.config,r=e.env,n=r.elb,i=r.window,u=_object_spread({name:"dataLayer",prefix:"dataLayer"},null==t?void 0:t.settings),l={settings:u},c=0,i&&(f=u.name||"dataLayer",y=i[f],c=Array.isArray(y)?y.length:0,function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:globalThis.window,n=t.settings,a=(null==n?void 0:n.name)||"dataLayer";r[a]||(r[a]=[]);var i=r[a];if(Array.isArray(i)){var u=i.push.bind(i);i.push=function(){for(var t=arguments.length,r=new Array(t),a=0;a<t;a++)r[a]=arguments[a];if(h)return u.apply(void 0,_to_consumable_array(r));h=!0;try{var i=!0,l=!1,c=void 0;try{for(var f,y=r[Symbol.iterator]();!(i=(f=y.next()).done);i=!0){var s=f.value;o(e,n,s)}}catch(e){l=!0,c=e}finally{try{i||null==y.return||y.return()}finally{if(l)throw c}}}finally{h=!1}return u.apply(void 0,_to_consumable_array(r))}}}(n,l,s=i),e.collector.allowed&&c>0&&(a(n,l,c,s),c=0)),[2,{type:"dataLayer",config:l,push:n,on:function(e){return _async_to_generator(function(){return _ts_generator(this,function(t){return"run"===e&&i&&c>0&&(a(n,l,c,i),c=0),[2]})})()},destroy:function(){return _async_to_generator(function(){var e;return _ts_generator(this,function(t){return e=u.name||"dataLayer",i&&i[e]&&Array.isArray(i[e]),[2]})})()}}]})})()},I=R;return L=p,function(e,t,r,n){if(t&&"object"===(void 0===t?"undefined":_type_of(t))||"function"==typeof t){var a=!0,o=!1,i=void 0;try{for(var u,l=function(){var a=u.value;s.call(e,a)||a===r||c(e,a,{get:function(){return t[a]},enumerable:!(n=f(t,a))||n.enumerable})},_=y(t)[Symbol.iterator]();!(a=(u=_.next()).done);a=!0)l()}catch(e){o=!0,i=e}finally{try{a||null==_.return||_.return()}finally{if(o)throw i}}}return e}(c({},"__esModule",{value:!0}),L)}();
|
|
1
|
+
"use strict";function _array_like_to_array(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function _array_with_holes(e){if(Array.isArray(e))return e}function _array_without_holes(e){if(Array.isArray(e))return _array_like_to_array(e)}function asyncGeneratorStep(e,t,r,n,a,o,i){try{var u=e[o](i),c=u.value}catch(e){return void r(e)}u.done?t(c):Promise.resolve(c).then(n,a)}function _async_to_generator(e){return function(){var t=this,r=arguments;return new Promise(function(n,a){var o=e.apply(t,r);function i(e){asyncGeneratorStep(o,n,a,i,u,"next",e)}function u(e){asyncGeneratorStep(o,n,a,i,u,"throw",e)}i(void 0)})}}function _define_property(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function _iterable_to_array(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _iterable_to_array_limit(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,o=[],i=!0,u=!1;try{for(r=r.call(e);!(i=(n=r.next()).done)&&(o.push(n.value),!t||o.length!==t);i=!0);}catch(e){u=!0,a=e}finally{try{i||null==r.return||r.return()}finally{if(u)throw a}}return o}}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _object_spread(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),n.forEach(function(t){_define_property(e,t,r[t])})}return e}function _object_without_properties(e,t){if(null==e)return{};var r,n,a,o={};if("undefined"!=typeof Reflect&&Reflect.ownKeys){for(r=Reflect.ownKeys(Object(e)),a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n]);return o}if(o=_object_without_properties_loose(e,t),Object.getOwnPropertySymbols)for(r=Object.getOwnPropertySymbols(e),a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n]);return o}function _object_without_properties_loose(e,t){if(null==e)return{};var r,n,a={},o=Object.getOwnPropertyNames(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r]);return a}function _sliced_to_array(e,t){return _array_with_holes(e)||_iterable_to_array_limit(e,t)||_unsupported_iterable_to_array(e,t)||_non_iterable_rest()}function _to_consumable_array(e){return _array_without_holes(e)||_iterable_to_array(e)||_unsupported_iterable_to_array(e)||_non_iterable_spread()}function _type_of(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e}function _unsupported_iterable_to_array(e,t){if(e){if("string"==typeof e)return _array_like_to_array(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(r):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_array_like_to_array(e,t):void 0}}function _ts_generator(e,t){var r,n,a,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype),u=Object.defineProperty;return u(i,"next",{value:c(0)}),u(i,"throw",{value:c(1)}),u(i,"return",{value:c(2)}),"function"==typeof Symbol&&u(i,Symbol.iterator,{value:function(){return this}}),i;function c(u){return function(c){return function(u){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,u[0]&&(o=0)),o;)try{if(r=1,n&&(a=2&u[0]?n.return:u[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,u[1])).done)return a;switch(n=0,a&&(u=[2&u[0],a.value]),u[0]){case 0:case 1:a=u;break;case 4:return o.label++,{value:u[1],done:!1};case 5:o.label++,n=u[1],u=[0];continue;case 7:u=o.ops.pop(),o.trys.pop();continue;default:if(!(a=o.trys,(a=a.length>0&&a[a.length-1])||6!==u[0]&&2!==u[0])){o=0;continue}if(3===u[0]&&(!a||u[1]>a[0]&&u[1]<a[3])){o.label=u[1];break}if(6===u[0]&&o.label<a[1]){o.label=a[1],a=u;break}if(a&&o.label<a[2]){o.label=a[2],o.ops.push(u);break}a[2]&&o.ops.pop(),o.trys.pop();continue}u=t.call(e,o)}catch(e){u=[6,e],n=0}finally{r=a=0}if(5&u[0])throw u[1];return{value:u[0]?u[1]:void 0,done:!0}}([u,c])}}}var Destination=function(){var e=function(e){return Array.isArray(e)},t=function(t){return"object"==(void 0===t?"undefined":_type_of(t))&&null!==t&&!e(t)&&"[object Object]"===Object.prototype.toString.call(t)},r=function(e){return"string"==typeof e},n=function(e,t,r){return function(){for(var n=arguments.length,a=new Array(n),o=0;o<n;o++)a[o]=arguments[o];try{return e.apply(void 0,_to_consumable_array(a))}catch(e){if(!t)return;return t(e)}finally{null==r||r()}}},a=function(e,t,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:globalThis.window,a=t.settings,i=n[(null==a?void 0:a.name)||"dataLayer"];if(Array.isArray(i)&&!m){m=!0;try{for(var u=null!=r?r:i.length,c=0;c<u;c++)o(e,a,i[c])}finally{m=!1}}},o=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2?arguments[2]:void 0;if(t.filter&&!0===n(function(){return t.filter(r)},function(){return!1})())return;var a=i(r);if(a){var o=t.prefix||"dataLayer",u="".concat(o," ").concat(a.name),c=(a.name,{name:u,data:_object_without_properties(a,["name"])});n(function(){return e(c)},function(){})()}},i=function(n){if(t(n)&&r(n.event))return _object_spread({name:n.event},_object_without_properties(n,["event"]));if(e(n)&&n.length>=2)return u(n);if(c(n)){var a=Array.from(n);return u(a)}return null},u=function(e){var n,a=_sliced_to_array(e,3),o=a[0],i=a[1],u=a[2];if(!r(o))return null;var c={};switch(o){case"consent":if(!r(i)||e.length<3)return null;if("default"!==i&&"update"!==i)return null;if(!t(u)||null===u)return null;n="".concat(o," ").concat(i),c=_object_spread({},u);break;case"event":if(!r(i))return null;n=i,t(u)&&(c=_object_spread({},u));break;case"config":if(!r(i))return null;n="".concat(o," ").concat(i),t(u)&&(c=_object_spread({},u));break;case"set":if(r(i))n="".concat(o," ").concat(i),t(u)&&(c=_object_spread({},u));else{if(!t(i))return null;n="".concat(o," custom"),c=_object_spread({},i)}break;default:return null}return _object_spread({name:n},c)},c=function(e){return null!=e&&"object"===(void 0===e?"undefined":_type_of(e))&&"length"in e&&"number"==typeof e.length&&e.length>0},l=Object.defineProperty,y=Object.getOwnPropertyDescriptor,f=Object.getOwnPropertyNames,_=Object.prototype.hasOwnProperty,s=function(e,t){for(var r in t)l(e,r,{get:t[r],enumerable:!0})},d={};s(d,{SourceDataLayer:function(){return h},default:function(){return T},env:function(){return g},setup:function(){return x},sourceDataLayer:function(){return I},step:function(){return L}});var p=Object.defineProperty;!function(e,t){for(var r in t)p(e,r,{get:t[r],enumerable:!0})}({},{Level:function(){return v}});var b,v=((b=v||{})[b.ERROR=0]="ERROR",b[b.WARN=1]="WARN",b[b.INFO=2]="INFO",b[b.DEBUG=3]="DEBUG",b),m=!1,h={},g={};s(g,{push:function(){return S}});var w=function(){},j=function(){return function(){return Promise.resolve({ok:!0})}},O={error:w,warn:w,info:w,debug:w,throw:function(e){throw"string"==typeof e?new Error(e):e},json:w,scope:function(){return O}},S={get push(){return j()},get command(){return j()},get elb(){return j()},get window(){return{dataLayer:[],addEventListener:w,removeEventListener:w}},logger:O},L={};s(L,{consentUpdate:function(){return P},directEvent:function(){return U},gtagAddToCart:function(){return R},gtagPurchase:function(){return E},gtagViewItem:function(){return k}});var A,E={in:["event","purchase",{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]}],out:{name:"dataLayer purchase",data:{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]},entity:"dataLayer",action:"purchase"}},P={in:["consent","update",{ad_storage:"granted",analytics_storage:"granted"}],out:{name:"dataLayer consent update",data:{ad_storage:"granted",analytics_storage:"granted"},entity:"dataLayer",action:"consent update"}},R={in:["event","add_to_cart",{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]}],out:{name:"dataLayer add_to_cart",data:{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]},entity:"dataLayer",action:"add_to_cart"}},k={in:["event","view_item",{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]}],out:{name:"dataLayer view_item",data:{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]},entity:"dataLayer",action:"view_item"}},U={in:{event:"custom_event",category:"engagement",label:"video_play"},out:{name:"dataLayer custom_event",data:{category:"engagement",label:"video_play"},entity:"dataLayer",action:"custom_event"}},x=function(e,t){var r=t.window;if(r.dataLayer||(r.dataLayer=[]),Array.isArray(e)){var n=!0,a=!1,o=void 0;try{for(var i,u=e[Symbol.iterator]();!(n=(i=u.next()).done);n=!0){var c=i.value;r.dataLayer.push(c)}}catch(e){a=!0,o=e}finally{try{n||null==u.return||u.return()}finally{if(a)throw o}}}else e&&"object"===(void 0===e?"undefined":_type_of(e))&&r.dataLayer.push(e)},I=function(e){return _async_to_generator(function(){var t,r,n,i,u,c,l,y,f,_;return _ts_generator(this,function(s){return t=e.config,r=e.env,n=r.elb,i=r.window,u=_object_spread({name:"dataLayer",prefix:"dataLayer"},null==t?void 0:t.settings),c={settings:u},l=0,i&&(y=u.name||"dataLayer",f=i[y],l=Array.isArray(f)?f.length:0,function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:globalThis.window,n=t.settings,a=(null==n?void 0:n.name)||"dataLayer";r[a]||(r[a]=[]);var i=r[a];if(Array.isArray(i)){var u=i.push.bind(i);i.push=function(){for(var t=arguments.length,r=new Array(t),a=0;a<t;a++)r[a]=arguments[a];if(m)return u.apply(void 0,_to_consumable_array(r));m=!0;try{var i=!0,c=!1,l=void 0;try{for(var y,f=r[Symbol.iterator]();!(i=(y=f.next()).done);i=!0){var _=y.value;o(e,n,_)}}catch(e){c=!0,l=e}finally{try{i||null==f.return||f.return()}finally{if(c)throw l}}}finally{m=!1}return u.apply(void 0,_to_consumable_array(r))}}}(n,c,_=i),e.collector.allowed&&l>0&&(a(n,c,l,_),l=0)),[2,{type:"dataLayer",config:c,push:n,on:function(e){return _async_to_generator(function(){return _ts_generator(this,function(t){return"run"===e&&i&&l>0&&(a(n,c,l,i),l=0),[2]})})()},destroy:function(){return _async_to_generator(function(){var e;return _ts_generator(this,function(t){return e=u.name||"dataLayer",i&&i[e]&&Array.isArray(i[e]),[2]})})()}}]})})()},T=I;return A=d,function(e,t,r,n){if(t&&"object"===(void 0===t?"undefined":_type_of(t))||"function"==typeof t){var a=!0,o=!1,i=void 0;try{for(var u,c=function(){var a=u.value;_.call(e,a)||a===r||l(e,a,{get:function(){return t[a]},enumerable:!(n=y(t,a))||n.enumerable})},s=f(t)[Symbol.iterator]();!(a=(u=s.next()).done);a=!0)c()}catch(e){o=!0,i=e}finally{try{a||null==s.return||s.return()}finally{if(o)throw i}}}return e}(l({},"__esModule",{value:!0}),A)}();
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,i=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},o={};i(o,{SourceDataLayer:()=>y,default:()=>O,env:()=>m,setup:()=>j,sourceDataLayer:()=>A,step:()=>v}),module.exports=(e=o,((e,i,o,s)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let c of r(i))n.call(e,c)||c===o||t(e,c,{get:()=>i[c],enumerable:!(s=a(i,c))||s.enumerable});return e})(t({},"__esModule",{value:!0}),e));var s=require("@walkeros/core"),c=!1;function u(e,t,a,r=globalThis.window){const n=t.settings,i=r[(null==n?void 0:n.name)||"dataLayer"];if(Array.isArray(i)&&!c){c=!0;try{const t=null!=a?a:i.length;for(let a=0;a<t;a++)l(e,n,i[a])}finally{c=!1}}}function l(e,t={},a){if(t.filter){if(!0===(0,s.tryCatch)(()=>t.filter(a),()=>!1)())return}const r=function(e){if((0,s.isObject)(e)&&(0,s.isString)(e.event)){const{event:t,...a}=e;return{name:t,...a}}if((0,s.isArray)(e)&&e.length>=2)return d(e);if(t=e,null!=t&&"object"==typeof t&&"length"in t&&"number"==typeof t.length&&t.length>0){return d(Array.from(e))}var t;return null}(a);if(!r)return;const n=`${t.prefix||"dataLayer"} ${r.name}`,{name:i,...o}=r,c={name:n,data:o};(0,s.tryCatch)(()=>e(c),()=>{})()}function d(e){const[t,a,r]=e;if(!(0,s.isString)(t))return null;let n,i={};switch(t){case"consent":if(!(0,s.isString)(a)||e.length<3)return null;if("default"!==a&&"update"!==a)return null;if(!(0,s.isObject)(r)||null===r)return null;n=`${t} ${a}`,i={...r};break;case"event":if(!(0,s.isString)(a))return null;n=a,(0,s.isObject)(r)&&(i={...r});break;case"config":if(!(0,s.isString)(a))return null;n=`${t} ${a}`,(0,s.isObject)(r)&&(i={...r});break;case"set":if((0,s.isString)(a))n=`${t} ${a}`,(0,s.isObject)(r)&&(i={...r});else{if(!(0,s.isObject)(a))return null;n=`${t} custom`,i={...a}}break;default:return null}return{name:n,...i}}var y={},m={};i(m,{push:()=>p});var f=()=>{},g=()=>()=>Promise.resolve({ok:!0}),_={error:f,warn:f,info:f,debug:f,throw:e=>{throw"string"==typeof e?new Error(e):e},json:f,scope:()=>_},p={get push(){return g()},get command(){return g()},get elb(){return g()},get window(){return{dataLayer:[],addEventListener:f,removeEventListener:f}},logger:_},v={};i(v,{consentUpdate:()=>b,directEvent:()=>S,gtagAddToCart:()=>L,gtagPurchase:()=>h,gtagViewItem:()=>w});var h={in:["event","purchase",{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]}],out:{name:"dataLayer purchase",data:{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]},entity:"dataLayer",action:"purchase"}},b={in:["consent","update",{ad_storage:"granted",analytics_storage:"granted"}],out:{name:"dataLayer consent update",data:{ad_storage:"granted",analytics_storage:"granted"},entity:"dataLayer",action:"consent update"}},L={in:["event","add_to_cart",{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]}],out:{name:"dataLayer add_to_cart",data:{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]},entity:"dataLayer",action:"add_to_cart"}},w={in:["event","view_item",{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]}],out:{name:"dataLayer view_item",data:{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]},entity:"dataLayer",action:"view_item"}},S={in:{event:"custom_event",category:"engagement",label:"video_play"},out:{name:"dataLayer custom_event",data:{category:"engagement",label:"video_play"},entity:"dataLayer",action:"custom_event"}},j=(e,t)=>{const a=t.window;if(a.dataLayer||(a.dataLayer=[]),Array.isArray(e))for(const t of e)a.dataLayer.push(t);else e&&"object"==typeof e&&a.dataLayer.push(e)},A=async e=>{const{config:t,env:a}=e,{elb:r,window:n}=a,i={name:"dataLayer",prefix:"dataLayer",...null==t?void 0:t.settings},o={settings:i};let s=0;if(n){const t=i.name||"dataLayer",a=n[t];s=Array.isArray(a)?a.length:0;const d=n;!function(e,t,a=globalThis.window){const r=t.settings,n=(null==r?void 0:r.name)||"dataLayer";a[n]||(a[n]=[]);const i=a[n];if(!Array.isArray(i))return;const o=i.push.bind(i);i.push=function(...t){if(c)return o(...t);c=!0;try{for(const a of t)l(e,r,a)}finally{c=!1}return o(...t)}}(r,o,d),e.collector.allowed&&s>0&&(u(r,o,s,d),s=0)}return{type:"dataLayer",config:o,push:r,on:async e=>{if("run"===e&&n&&s>0){u(r,o,s,n),s=0}},destroy:async()=>{const e=i.name||"dataLayer";n&&n[e]&&Array.isArray(n[e])}}},O=A;//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/interceptor.ts","../src/types/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/setup.ts"],"sourcesContent":["import type { Source, On } from '@walkeros/core';\nimport type { Types } from './types';\nimport { interceptDataLayer, processExistingEvents } from './interceptor';\n\n// Export types for external usage\nexport * as SourceDataLayer from './types';\n\n// Export examples\nexport * from './examples';\n\n/**\n * DataLayer source implementation using environment injection.\n *\n * This source intercepts dataLayer.push calls and transforms them to WalkerOS events.\n * It works by replacing the dataLayer.push method with a custom handler.\n */\nexport const sourceDataLayer: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, window: envWindow } = env;\n\n const settings: Source.Settings<Types> = {\n name: 'dataLayer',\n prefix: 'dataLayer',\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n let pendingReplayCount = 0;\n\n if (envWindow) {\n // Snapshot how many items exist before interception\n const dataLayerName = settings.name || 'dataLayer';\n const dl = (envWindow as Record<string, unknown>)[dataLayerName];\n pendingReplayCount = Array.isArray(dl) ? dl.length : 0;\n\n const win = envWindow as unknown as Record<string, unknown>;\n\n // Set up interceptor immediately so no new events are missed\n interceptDataLayer(elb, fullConfig, win);\n\n if (context.collector.allowed && pendingReplayCount > 0) {\n // Collector already ran — process existing events immediately\n processExistingEvents(elb, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n }\n\n // Handle on-run to replay existing events (when source inits before run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'run' && envWindow && pendingReplayCount > 0) {\n const win = envWindow as unknown as Record<string, unknown>;\n processExistingEvents(elb, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n };\n\n return {\n type: 'dataLayer',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n destroy: async () => {\n // Cleanup: restore original dataLayer.push if possible\n const dataLayerName = settings.name || 'dataLayer';\n if (\n envWindow &&\n envWindow[dataLayerName] &&\n Array.isArray(envWindow[dataLayerName])\n ) {\n // Note: Complete restoration would require storing original push method\n // For now, we'll just document this limitation\n }\n },\n };\n};\n\nexport default sourceDataLayer;\n","import type { WalkerOS, Source, Collector } from '@walkeros/core';\nimport { isArray, isObject, isString, tryCatch } from '@walkeros/core';\n\n// Global flag to prevent infinite loops\nlet isProcessing = false;\n\n/**\n * DataLayer interceptor - handles dataLayer.push interception and event transformation\n */\nexport function interceptDataLayer(\n push: Collector.PushFn,\n config: Source.Config,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n\n // Ensure dataLayer exists\n if (!win[dataLayerName]) {\n win[dataLayerName] = [];\n }\n\n const dataLayer = win[dataLayerName] as unknown[];\n if (!Array.isArray(dataLayer)) return;\n\n // Store original push\n const originalPush = dataLayer.push.bind(dataLayer);\n\n // Override push with event processing\n dataLayer.push = function (...args: unknown[]): number {\n // Prevent infinite loops\n if (isProcessing) {\n return originalPush(...args);\n }\n\n isProcessing = true;\n try {\n // Process each argument\n for (const arg of args) {\n processEvent(push, settings, arg);\n }\n } finally {\n isProcessing = false;\n }\n\n // Call original push\n return originalPush(...args);\n };\n}\n\n/**\n * Process existing events on initialization\n */\nexport function processExistingEvents(\n push: Collector.PushFn,\n config: Source.Config,\n limit?: number,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n const dataLayer = win[dataLayerName] as unknown[];\n\n if (!Array.isArray(dataLayer)) return;\n\n // Prevent loops during initialization\n if (isProcessing) return;\n\n isProcessing = true;\n try {\n const count = limit ?? dataLayer.length;\n for (let i = 0; i < count; i++) {\n processEvent(push, settings, dataLayer[i]);\n }\n } finally {\n isProcessing = false;\n }\n}\n\n/**\n * Process a single event - handles filtering, transformation, and WalkerOS event creation\n */\nfunction processEvent(\n push: Collector.PushFn,\n settings: { prefix?: string; filter?: (event: unknown) => boolean } = {},\n rawEvent: unknown,\n): void {\n // Apply filter if provided\n if (settings.filter) {\n const filterFn = tryCatch(\n () => settings.filter!(rawEvent),\n () => false, // If filter throws, don't skip the event\n );\n const filterResult = filterFn();\n if (filterResult === true) {\n return; // Skip filtered events\n }\n }\n\n // Transform the event (handles gtag format and direct objects)\n const transformedEvent = transformDataLayerEvent(rawEvent);\n if (!transformedEvent) {\n return; // Skip invalid events\n }\n\n const prefix = settings.prefix || 'dataLayer';\n const eventName = `${prefix} ${transformedEvent.name}`;\n\n // Create partial WalkerOS event structure (collector will enrich it)\n const { name: _name, ...data } = transformedEvent;\n const partialEvent: WalkerOS.DeepPartialEvent = {\n name: eventName,\n data: data as WalkerOS.Properties,\n };\n\n // Push to collector\n tryCatch(\n () => push(partialEvent),\n () => {}, // Silently handle push errors\n )();\n}\n\n/**\n * Transform dataLayer events to standardized format\n * Handles: gtag arguments, direct objects, existing events\n */\nfunction transformDataLayerEvent(\n rawEvent: unknown,\n): { name: string; [key: string]: unknown } | null {\n // Handle direct object format: { event: 'test', data: 'value' }\n if (isObject(rawEvent) && isString(rawEvent.event)) {\n const { event, ...rest } = rawEvent;\n return { name: event, ...rest };\n }\n\n // Handle gtag argument format: ['consent', 'update', { ad_storage: 'granted' }]\n if (isArray(rawEvent) && rawEvent.length >= 2) {\n return transformGtagArgs(rawEvent);\n }\n\n // Handle arguments object (from gtag function calls)\n if (isGtagArguments(rawEvent)) {\n const argsArray = Array.from(rawEvent as ArrayLike<unknown>);\n return transformGtagArgs(argsArray);\n }\n\n return null;\n}\n\n/**\n * Transform gtag-style arguments to event object\n * ['consent', 'update', { ad_storage: 'granted' }] → { event: 'consent update', ad_storage: 'granted' }\n */\nfunction transformGtagArgs(\n args: unknown[],\n): { name: string; [key: string]: unknown } | null {\n const [command, action, params] = args;\n\n if (!isString(command)) return null;\n\n let eventName: string;\n let eventData: Record<string, unknown> = {};\n\n switch (command) {\n case 'consent':\n // Consent requires action and params\n if (!isString(action) || args.length < 3) return null;\n // Only allow 'default' and 'update' actions for consent\n if (action !== 'default' && action !== 'update') return null;\n // Params must be a valid object (not null)\n if (!isObject(params) || params === null) return null;\n\n eventName = `${command} ${action}`;\n eventData = { ...params };\n break;\n\n case 'event':\n // Event requires at least action parameter\n if (!isString(action)) return null;\n eventName = action;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'config':\n // Config requires at least action parameter\n if (!isString(action)) return null;\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'set':\n if (isString(action)) {\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n } else if (isObject(action)) {\n eventName = `${command} custom`;\n eventData = { ...action };\n } else {\n return null;\n }\n break;\n\n default:\n // Unknown command, ignore\n return null;\n }\n\n return {\n name: eventName,\n ...eventData,\n };\n}\n\n/**\n * Check if object is gtag arguments object\n */\nfunction isGtagArguments(obj: unknown): boolean {\n return (\n obj != null &&\n typeof obj === 'object' &&\n 'length' in obj &&\n typeof (obj as ArrayLike<unknown>).length === 'number' &&\n (obj as ArrayLike<unknown>).length > 0\n );\n}\n","import type { WalkerOS, Source, Elb } from '@walkeros/core';\nimport type { SettingsSchema } from '../schemas';\nimport { z } from '@walkeros/core/dev';\n\ndeclare global {\n interface Window {\n dataLayer?: DataLayer;\n [key: string]: DataLayer | unknown;\n }\n}\n\nexport type DataLayer = Array<unknown>;\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// Override filter to be actual function type (not serializable in schema)\nexport interface Settings extends Omit<BaseSettings, 'filter'> {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => WalkerOS.PromiseOrValue<boolean>;\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport type DataLayerEvent = {\n event: string;\n [key: string]: unknown;\n};\n\nexport type MappedEvent = {\n event?: WalkerOS.DeepPartialEvent & { id: string };\n command?: {\n name: string;\n data: unknown;\n };\n};\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n entity: 'dataLayer',\n action: 'purchase',\n },\n};\n\nexport const consentUpdate: Flow.StepExample = {\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n entity: 'dataLayer',\n action: 'consent update',\n },\n};\n\nexport const directEvent: Flow.StepExample = {\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n entity: 'dataLayer',\n action: 'custom_event',\n },\n};\n","import type { Source } from '@walkeros/core';\n\n/** Prepopulates window.dataLayer before source init. */\nexport const setup: Source.SetupFn = (input, env) => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n\n if (Array.isArray(input)) {\n for (const item of input) win.dataLayer.push(item);\n } else if (input && typeof input === 'object') {\n win.dataLayer.push(input);\n }\n};\n"],"mappings":"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","names":["push"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/interceptor.ts","../src/types/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/setup.ts"],"sourcesContent":["import type { Source, On } from '@walkeros/core';\nimport type { Types } from './types';\nimport { interceptDataLayer, processExistingEvents } from './interceptor';\n\n// Export types for external usage\nexport * as SourceDataLayer from './types';\n\n// Export examples\nexport * from './examples';\n\n/**\n * DataLayer source implementation using environment injection.\n *\n * This source intercepts dataLayer.push calls and transforms them to WalkerOS events.\n * It works by replacing the dataLayer.push method with a custom handler.\n */\nexport const sourceDataLayer: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, window: envWindow } = env;\n\n const settings: Source.Settings<Types> = {\n name: 'dataLayer',\n prefix: 'dataLayer',\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n let pendingReplayCount = 0;\n\n if (envWindow) {\n // Snapshot how many items exist before interception\n const dataLayerName = settings.name || 'dataLayer';\n const dl = (envWindow as Record<string, unknown>)[dataLayerName];\n pendingReplayCount = Array.isArray(dl) ? dl.length : 0;\n\n const win = envWindow as unknown as Record<string, unknown>;\n\n // Set up interceptor immediately so no new events are missed\n interceptDataLayer(elb, fullConfig, win);\n\n if (context.collector.allowed && pendingReplayCount > 0) {\n // Collector already ran — process existing events immediately\n processExistingEvents(elb, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n }\n\n // Handle on-run to replay existing events (when source inits before run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'run' && envWindow && pendingReplayCount > 0) {\n const win = envWindow as unknown as Record<string, unknown>;\n processExistingEvents(elb, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n };\n\n return {\n type: 'dataLayer',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n destroy: async () => {\n // Cleanup: restore original dataLayer.push if possible\n const dataLayerName = settings.name || 'dataLayer';\n if (\n envWindow &&\n envWindow[dataLayerName] &&\n Array.isArray(envWindow[dataLayerName])\n ) {\n // Note: Complete restoration would require storing original push method\n // For now, we'll just document this limitation\n }\n },\n };\n};\n\nexport default sourceDataLayer;\n","import type { WalkerOS, Source, Collector } from '@walkeros/core';\nimport { isArray, isObject, isString, tryCatch } from '@walkeros/core';\n\n// Global flag to prevent infinite loops\nlet isProcessing = false;\n\n/**\n * DataLayer interceptor - handles dataLayer.push interception and event transformation\n */\nexport function interceptDataLayer(\n push: Collector.PushFn,\n config: Source.Config,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n\n // Ensure dataLayer exists\n if (!win[dataLayerName]) {\n win[dataLayerName] = [];\n }\n\n const dataLayer = win[dataLayerName] as unknown[];\n if (!Array.isArray(dataLayer)) return;\n\n // Store original push\n const originalPush = dataLayer.push.bind(dataLayer);\n\n // Override push with event processing\n dataLayer.push = function (...args: unknown[]): number {\n // Prevent infinite loops\n if (isProcessing) {\n return originalPush(...args);\n }\n\n isProcessing = true;\n try {\n // Process each argument\n for (const arg of args) {\n processEvent(push, settings, arg);\n }\n } finally {\n isProcessing = false;\n }\n\n // Call original push\n return originalPush(...args);\n };\n}\n\n/**\n * Process existing events on initialization\n */\nexport function processExistingEvents(\n push: Collector.PushFn,\n config: Source.Config,\n limit?: number,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n const dataLayer = win[dataLayerName] as unknown[];\n\n if (!Array.isArray(dataLayer)) return;\n\n // Prevent loops during initialization\n if (isProcessing) return;\n\n isProcessing = true;\n try {\n const count = limit ?? dataLayer.length;\n for (let i = 0; i < count; i++) {\n processEvent(push, settings, dataLayer[i]);\n }\n } finally {\n isProcessing = false;\n }\n}\n\n/**\n * Process a single event - handles filtering, transformation, and WalkerOS event creation\n */\nfunction processEvent(\n push: Collector.PushFn,\n settings: { prefix?: string; filter?: (event: unknown) => boolean } = {},\n rawEvent: unknown,\n): void {\n // Apply filter if provided\n if (settings.filter) {\n const filterFn = tryCatch(\n () => settings.filter!(rawEvent),\n () => false, // If filter throws, don't skip the event\n );\n const filterResult = filterFn();\n if (filterResult === true) {\n return; // Skip filtered events\n }\n }\n\n // Transform the event (handles gtag format and direct objects)\n const transformedEvent = transformDataLayerEvent(rawEvent);\n if (!transformedEvent) {\n return; // Skip invalid events\n }\n\n const prefix = settings.prefix || 'dataLayer';\n const eventName = `${prefix} ${transformedEvent.name}`;\n\n // Create partial WalkerOS event structure (collector will enrich it)\n const { name: _name, ...data } = transformedEvent;\n const partialEvent: WalkerOS.DeepPartialEvent = {\n name: eventName,\n data: data as WalkerOS.Properties,\n };\n\n // Push to collector\n tryCatch(\n () => push(partialEvent),\n () => {}, // Silently handle push errors\n )();\n}\n\n/**\n * Transform dataLayer events to standardized format\n * Handles: gtag arguments, direct objects, existing events\n */\nfunction transformDataLayerEvent(\n rawEvent: unknown,\n): { name: string; [key: string]: unknown } | null {\n // Handle direct object format: { event: 'test', data: 'value' }\n if (isObject(rawEvent) && isString(rawEvent.event)) {\n const { event, ...rest } = rawEvent;\n return { name: event, ...rest };\n }\n\n // Handle gtag argument format: ['consent', 'update', { ad_storage: 'granted' }]\n if (isArray(rawEvent) && rawEvent.length >= 2) {\n return transformGtagArgs(rawEvent);\n }\n\n // Handle arguments object (from gtag function calls)\n if (isGtagArguments(rawEvent)) {\n const argsArray = Array.from(rawEvent as ArrayLike<unknown>);\n return transformGtagArgs(argsArray);\n }\n\n return null;\n}\n\n/**\n * Transform gtag-style arguments to event object\n * ['consent', 'update', { ad_storage: 'granted' }] → { event: 'consent update', ad_storage: 'granted' }\n */\nfunction transformGtagArgs(\n args: unknown[],\n): { name: string; [key: string]: unknown } | null {\n const [command, action, params] = args;\n\n if (!isString(command)) return null;\n\n let eventName: string;\n let eventData: Record<string, unknown> = {};\n\n switch (command) {\n case 'consent':\n // Consent requires action and params\n if (!isString(action) || args.length < 3) return null;\n // Only allow 'default' and 'update' actions for consent\n if (action !== 'default' && action !== 'update') return null;\n // Params must be a valid object (not null)\n if (!isObject(params) || params === null) return null;\n\n eventName = `${command} ${action}`;\n eventData = { ...params };\n break;\n\n case 'event':\n // Event requires at least action parameter\n if (!isString(action)) return null;\n eventName = action;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'config':\n // Config requires at least action parameter\n if (!isString(action)) return null;\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'set':\n if (isString(action)) {\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n } else if (isObject(action)) {\n eventName = `${command} custom`;\n eventData = { ...action };\n } else {\n return null;\n }\n break;\n\n default:\n // Unknown command, ignore\n return null;\n }\n\n return {\n name: eventName,\n ...eventData,\n };\n}\n\n/**\n * Check if object is gtag arguments object\n */\nfunction isGtagArguments(obj: unknown): boolean {\n return (\n obj != null &&\n typeof obj === 'object' &&\n 'length' in obj &&\n typeof (obj as ArrayLike<unknown>).length === 'number' &&\n (obj as ArrayLike<unknown>).length > 0\n );\n}\n","import type { WalkerOS, Source, Elb } from '@walkeros/core';\nimport type { SettingsSchema } from '../schemas';\nimport { z } from '@walkeros/core/dev';\n\ndeclare global {\n interface Window {\n dataLayer?: DataLayer;\n [key: string]: DataLayer | unknown;\n }\n}\n\nexport type DataLayer = Array<unknown>;\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// Override filter to be actual function type (not serializable in schema)\nexport interface Settings extends Omit<BaseSettings, 'filter'> {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => WalkerOS.PromiseOrValue<boolean>;\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport type DataLayerEvent = {\n event: string;\n [key: string]: unknown;\n};\n\nexport type MappedEvent = {\n event?: WalkerOS.DeepPartialEvent & { id: string };\n command?: {\n name: string;\n data: unknown;\n };\n};\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n entity: 'dataLayer',\n action: 'purchase',\n },\n};\n\nexport const consentUpdate: Flow.StepExample = {\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n entity: 'dataLayer',\n action: 'consent update',\n },\n};\n\nexport const gtagAddToCart: Flow.StepExample = {\n in: [\n 'event',\n 'add_to_cart',\n {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n ],\n out: {\n name: 'dataLayer add_to_cart',\n data: {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n entity: 'dataLayer',\n action: 'add_to_cart',\n },\n};\n\nexport const gtagViewItem: Flow.StepExample = {\n in: [\n 'event',\n 'view_item',\n {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n ],\n out: {\n name: 'dataLayer view_item',\n data: {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n entity: 'dataLayer',\n action: 'view_item',\n },\n};\n\nexport const directEvent: Flow.StepExample = {\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n entity: 'dataLayer',\n action: 'custom_event',\n },\n};\n","import type { Source } from '@walkeros/core';\n\n/** Prepopulates window.dataLayer before source init. */\nexport const setup: Source.SetupFn = (input, env) => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n\n if (Array.isArray(input)) {\n for (const item of input) win.dataLayer.push(item);\n } else if (input && typeof input === 'object') {\n win.dataLayer.push(input);\n }\n};\n"],"mappings":"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","names":["push"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=(t,a)=>{for(var n in a)e(t,n,{get:a[n],enumerable:!0})};import{isArray as a,isObject as n,isString as r,tryCatch as
|
|
1
|
+
var e=Object.defineProperty,t=(t,a)=>{for(var n in a)e(t,n,{get:a[n],enumerable:!0})};import{isArray as a,isObject as n,isString as r,tryCatch as i}from"@walkeros/core";var o=!1;function s(e,t,a,n=globalThis.window){const r=t.settings,i=n[(null==r?void 0:r.name)||"dataLayer"];if(Array.isArray(i)&&!o){o=!0;try{const t=null!=a?a:i.length;for(let a=0;a<t;a++)u(e,r,i[a])}finally{o=!1}}}function u(e,t={},o){if(t.filter){if(!0===i(()=>t.filter(o),()=>!1)())return}const s=function(e){if(n(e)&&r(e.event)){const{event:t,...a}=e;return{name:t,...a}}if(a(e)&&e.length>=2)return c(e);if(t=e,null!=t&&"object"==typeof t&&"length"in t&&"number"==typeof t.length&&t.length>0){return c(Array.from(e))}var t;return null}(o);if(!s)return;const u=`${t.prefix||"dataLayer"} ${s.name}`,{name:d,...l}=s,y={name:u,data:l};i(()=>e(y),()=>{})()}function c(e){const[t,a,i]=e;if(!r(t))return null;let o,s={};switch(t){case"consent":if(!r(a)||e.length<3)return null;if("default"!==a&&"update"!==a)return null;if(!n(i)||null===i)return null;o=`${t} ${a}`,s={...i};break;case"event":if(!r(a))return null;o=a,n(i)&&(s={...i});break;case"config":if(!r(a))return null;o=`${t} ${a}`,n(i)&&(s={...i});break;case"set":if(r(a))o=`${t} ${a}`,n(i)&&(s={...i});else{if(!n(a))return null;o=`${t} custom`,s={...a}}break;default:return null}return{name:o,...s}}var d={},l={};t(l,{push:()=>g});var y=()=>{},m=()=>()=>Promise.resolve({ok:!0}),f={error:y,warn:y,info:y,debug:y,throw:e=>{throw"string"==typeof e?new Error(e):e},json:y,scope:()=>f},g={get push(){return m()},get command(){return m()},get elb(){return m()},get window(){return{dataLayer:[],addEventListener:y,removeEventListener:y}},logger:f},v={};t(v,{consentUpdate:()=>p,directEvent:()=>w,gtagAddToCart:()=>h,gtagPurchase:()=>_,gtagViewItem:()=>L});var _={in:["event","purchase",{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]}],out:{name:"dataLayer purchase",data:{transaction_id:"T-12345",value:25.42,currency:"EUR",items:[{item_id:"SKU-1",item_name:"T-Shirt",quantity:1}]},entity:"dataLayer",action:"purchase"}},p={in:["consent","update",{ad_storage:"granted",analytics_storage:"granted"}],out:{name:"dataLayer consent update",data:{ad_storage:"granted",analytics_storage:"granted"},entity:"dataLayer",action:"consent update"}},h={in:["event","add_to_cart",{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]}],out:{name:"dataLayer add_to_cart",data:{currency:"EUR",value:15.25,items:[{item_id:"SKU_12345",item_name:"T-Shirt",item_variant:"red",quantity:1,price:15.25}]},entity:"dataLayer",action:"add_to_cart"}},L={in:["event","view_item",{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]}],out:{name:"dataLayer view_item",data:{currency:"EUR",value:29.99,items:[{item_id:"SKU_67890",item_name:"Sneakers",item_category:"Footwear",price:29.99}]},entity:"dataLayer",action:"view_item"}},w={in:{event:"custom_event",category:"engagement",label:"video_play"},out:{name:"dataLayer custom_event",data:{category:"engagement",label:"video_play"},entity:"dataLayer",action:"custom_event"}},b=(e,t)=>{const a=t.window;if(a.dataLayer||(a.dataLayer=[]),Array.isArray(e))for(const t of e)a.dataLayer.push(t);else e&&"object"==typeof e&&a.dataLayer.push(e)},S=async e=>{const{config:t,env:a}=e,{elb:n,window:r}=a,i={name:"dataLayer",prefix:"dataLayer",...null==t?void 0:t.settings},c={settings:i};let d=0;if(r){const t=i.name||"dataLayer",a=r[t];d=Array.isArray(a)?a.length:0;const l=r;!function(e,t,a=globalThis.window){const n=t.settings,r=(null==n?void 0:n.name)||"dataLayer";a[r]||(a[r]=[]);const i=a[r];if(!Array.isArray(i))return;const s=i.push.bind(i);i.push=function(...t){if(o)return s(...t);o=!0;try{for(const a of t)u(e,n,a)}finally{o=!1}return s(...t)}}(n,c,l),e.collector.allowed&&d>0&&(s(n,c,d,l),d=0)}return{type:"dataLayer",config:c,push:n,on:async e=>{if("run"===e&&r&&d>0){s(n,c,d,r),d=0}},destroy:async()=>{const e=i.name||"dataLayer";r&&r[e]&&Array.isArray(r[e])}}},U=S;export{d as SourceDataLayer,U as default,l as env,b as setup,S as sourceDataLayer,v as step};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interceptor.ts","../src/types/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/setup.ts","../src/index.ts"],"sourcesContent":["import type { WalkerOS, Source, Collector } from '@walkeros/core';\nimport { isArray, isObject, isString, tryCatch } from '@walkeros/core';\n\n// Global flag to prevent infinite loops\nlet isProcessing = false;\n\n/**\n * DataLayer interceptor - handles dataLayer.push interception and event transformation\n */\nexport function interceptDataLayer(\n push: Collector.PushFn,\n config: Source.Config,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n\n // Ensure dataLayer exists\n if (!win[dataLayerName]) {\n win[dataLayerName] = [];\n }\n\n const dataLayer = win[dataLayerName] as unknown[];\n if (!Array.isArray(dataLayer)) return;\n\n // Store original push\n const originalPush = dataLayer.push.bind(dataLayer);\n\n // Override push with event processing\n dataLayer.push = function (...args: unknown[]): number {\n // Prevent infinite loops\n if (isProcessing) {\n return originalPush(...args);\n }\n\n isProcessing = true;\n try {\n // Process each argument\n for (const arg of args) {\n processEvent(push, settings, arg);\n }\n } finally {\n isProcessing = false;\n }\n\n // Call original push\n return originalPush(...args);\n };\n}\n\n/**\n * Process existing events on initialization\n */\nexport function processExistingEvents(\n push: Collector.PushFn,\n config: Source.Config,\n limit?: number,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n const dataLayer = win[dataLayerName] as unknown[];\n\n if (!Array.isArray(dataLayer)) return;\n\n // Prevent loops during initialization\n if (isProcessing) return;\n\n isProcessing = true;\n try {\n const count = limit ?? dataLayer.length;\n for (let i = 0; i < count; i++) {\n processEvent(push, settings, dataLayer[i]);\n }\n } finally {\n isProcessing = false;\n }\n}\n\n/**\n * Process a single event - handles filtering, transformation, and WalkerOS event creation\n */\nfunction processEvent(\n push: Collector.PushFn,\n settings: { prefix?: string; filter?: (event: unknown) => boolean } = {},\n rawEvent: unknown,\n): void {\n // Apply filter if provided\n if (settings.filter) {\n const filterFn = tryCatch(\n () => settings.filter!(rawEvent),\n () => false, // If filter throws, don't skip the event\n );\n const filterResult = filterFn();\n if (filterResult === true) {\n return; // Skip filtered events\n }\n }\n\n // Transform the event (handles gtag format and direct objects)\n const transformedEvent = transformDataLayerEvent(rawEvent);\n if (!transformedEvent) {\n return; // Skip invalid events\n }\n\n const prefix = settings.prefix || 'dataLayer';\n const eventName = `${prefix} ${transformedEvent.name}`;\n\n // Create partial WalkerOS event structure (collector will enrich it)\n const { name: _name, ...data } = transformedEvent;\n const partialEvent: WalkerOS.DeepPartialEvent = {\n name: eventName,\n data: data as WalkerOS.Properties,\n };\n\n // Push to collector\n tryCatch(\n () => push(partialEvent),\n () => {}, // Silently handle push errors\n )();\n}\n\n/**\n * Transform dataLayer events to standardized format\n * Handles: gtag arguments, direct objects, existing events\n */\nfunction transformDataLayerEvent(\n rawEvent: unknown,\n): { name: string; [key: string]: unknown } | null {\n // Handle direct object format: { event: 'test', data: 'value' }\n if (isObject(rawEvent) && isString(rawEvent.event)) {\n const { event, ...rest } = rawEvent;\n return { name: event, ...rest };\n }\n\n // Handle gtag argument format: ['consent', 'update', { ad_storage: 'granted' }]\n if (isArray(rawEvent) && rawEvent.length >= 2) {\n return transformGtagArgs(rawEvent);\n }\n\n // Handle arguments object (from gtag function calls)\n if (isGtagArguments(rawEvent)) {\n const argsArray = Array.from(rawEvent as ArrayLike<unknown>);\n return transformGtagArgs(argsArray);\n }\n\n return null;\n}\n\n/**\n * Transform gtag-style arguments to event object\n * ['consent', 'update', { ad_storage: 'granted' }] → { event: 'consent update', ad_storage: 'granted' }\n */\nfunction transformGtagArgs(\n args: unknown[],\n): { name: string; [key: string]: unknown } | null {\n const [command, action, params] = args;\n\n if (!isString(command)) return null;\n\n let eventName: string;\n let eventData: Record<string, unknown> = {};\n\n switch (command) {\n case 'consent':\n // Consent requires action and params\n if (!isString(action) || args.length < 3) return null;\n // Only allow 'default' and 'update' actions for consent\n if (action !== 'default' && action !== 'update') return null;\n // Params must be a valid object (not null)\n if (!isObject(params) || params === null) return null;\n\n eventName = `${command} ${action}`;\n eventData = { ...params };\n break;\n\n case 'event':\n // Event requires at least action parameter\n if (!isString(action)) return null;\n eventName = action;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'config':\n // Config requires at least action parameter\n if (!isString(action)) return null;\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'set':\n if (isString(action)) {\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n } else if (isObject(action)) {\n eventName = `${command} custom`;\n eventData = { ...action };\n } else {\n return null;\n }\n break;\n\n default:\n // Unknown command, ignore\n return null;\n }\n\n return {\n name: eventName,\n ...eventData,\n };\n}\n\n/**\n * Check if object is gtag arguments object\n */\nfunction isGtagArguments(obj: unknown): boolean {\n return (\n obj != null &&\n typeof obj === 'object' &&\n 'length' in obj &&\n typeof (obj as ArrayLike<unknown>).length === 'number' &&\n (obj as ArrayLike<unknown>).length > 0\n );\n}\n","import type { WalkerOS, Source, Elb } from '@walkeros/core';\nimport type { SettingsSchema } from '../schemas';\nimport { z } from '@walkeros/core/dev';\n\ndeclare global {\n interface Window {\n dataLayer?: DataLayer;\n [key: string]: DataLayer | unknown;\n }\n}\n\nexport type DataLayer = Array<unknown>;\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// Override filter to be actual function type (not serializable in schema)\nexport interface Settings extends Omit<BaseSettings, 'filter'> {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => WalkerOS.PromiseOrValue<boolean>;\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport type DataLayerEvent = {\n event: string;\n [key: string]: unknown;\n};\n\nexport type MappedEvent = {\n event?: WalkerOS.DeepPartialEvent & { id: string };\n command?: {\n name: string;\n data: unknown;\n };\n};\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n entity: 'dataLayer',\n action: 'purchase',\n },\n};\n\nexport const consentUpdate: Flow.StepExample = {\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n entity: 'dataLayer',\n action: 'consent update',\n },\n};\n\nexport const directEvent: Flow.StepExample = {\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n entity: 'dataLayer',\n action: 'custom_event',\n },\n};\n","import type { Source } from '@walkeros/core';\n\n/** Prepopulates window.dataLayer before source init. */\nexport const setup: Source.SetupFn = (input, env) => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n\n if (Array.isArray(input)) {\n for (const item of input) win.dataLayer.push(item);\n } else if (input && typeof input === 'object') {\n win.dataLayer.push(input);\n }\n};\n","import type { Source, On } from '@walkeros/core';\nimport type { Types } from './types';\nimport { interceptDataLayer, processExistingEvents } from './interceptor';\n\n// Export types for external usage\nexport * as SourceDataLayer from './types';\n\n// Export examples\nexport * from './examples';\n\n/**\n * DataLayer source implementation using environment injection.\n *\n * This source intercepts dataLayer.push calls and transforms them to WalkerOS events.\n * It works by replacing the dataLayer.push method with a custom handler.\n */\nexport const sourceDataLayer: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, window: envWindow } = env;\n\n const settings: Source.Settings<Types> = {\n name: 'dataLayer',\n prefix: 'dataLayer',\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n let pendingReplayCount = 0;\n\n if (envWindow) {\n // Snapshot how many items exist before interception\n const dataLayerName = settings.name || 'dataLayer';\n const dl = (envWindow as Record<string, unknown>)[dataLayerName];\n pendingReplayCount = Array.isArray(dl) ? dl.length : 0;\n\n const win = envWindow as unknown as Record<string, unknown>;\n\n // Set up interceptor immediately so no new events are missed\n interceptDataLayer(elb, fullConfig, win);\n\n if (context.collector.allowed && pendingReplayCount > 0) {\n // Collector already ran — process existing events immediately\n processExistingEvents(elb, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n }\n\n // Handle on-run to replay existing events (when source inits before run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'run' && envWindow && pendingReplayCount > 0) {\n const win = envWindow as unknown as Record<string, unknown>;\n processExistingEvents(elb, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n };\n\n return {\n type: 'dataLayer',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n destroy: async () => {\n // Cleanup: restore original dataLayer.push if possible\n const dataLayerName = settings.name || 'dataLayer';\n if (\n envWindow &&\n envWindow[dataLayerName] &&\n Array.isArray(envWindow[dataLayerName])\n ) {\n // Note: Complete restoration would require storing original push method\n // For now, we'll just document this limitation\n }\n },\n };\n};\n\nexport default sourceDataLayer;\n"],"mappings":"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","names":["push"]}
|
|
1
|
+
{"version":3,"sources":["../src/interceptor.ts","../src/types/index.ts","../src/examples/env.ts","../src/examples/step.ts","../src/examples/setup.ts","../src/index.ts"],"sourcesContent":["import type { WalkerOS, Source, Collector } from '@walkeros/core';\nimport { isArray, isObject, isString, tryCatch } from '@walkeros/core';\n\n// Global flag to prevent infinite loops\nlet isProcessing = false;\n\n/**\n * DataLayer interceptor - handles dataLayer.push interception and event transformation\n */\nexport function interceptDataLayer(\n push: Collector.PushFn,\n config: Source.Config,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n\n // Ensure dataLayer exists\n if (!win[dataLayerName]) {\n win[dataLayerName] = [];\n }\n\n const dataLayer = win[dataLayerName] as unknown[];\n if (!Array.isArray(dataLayer)) return;\n\n // Store original push\n const originalPush = dataLayer.push.bind(dataLayer);\n\n // Override push with event processing\n dataLayer.push = function (...args: unknown[]): number {\n // Prevent infinite loops\n if (isProcessing) {\n return originalPush(...args);\n }\n\n isProcessing = true;\n try {\n // Process each argument\n for (const arg of args) {\n processEvent(push, settings, arg);\n }\n } finally {\n isProcessing = false;\n }\n\n // Call original push\n return originalPush(...args);\n };\n}\n\n/**\n * Process existing events on initialization\n */\nexport function processExistingEvents(\n push: Collector.PushFn,\n config: Source.Config,\n limit?: number,\n win: Record<string, unknown> = globalThis.window as unknown as Record<\n string,\n unknown\n >,\n): void {\n const settings = config.settings as {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => boolean;\n };\n const dataLayerName = settings?.name || 'dataLayer';\n const dataLayer = win[dataLayerName] as unknown[];\n\n if (!Array.isArray(dataLayer)) return;\n\n // Prevent loops during initialization\n if (isProcessing) return;\n\n isProcessing = true;\n try {\n const count = limit ?? dataLayer.length;\n for (let i = 0; i < count; i++) {\n processEvent(push, settings, dataLayer[i]);\n }\n } finally {\n isProcessing = false;\n }\n}\n\n/**\n * Process a single event - handles filtering, transformation, and WalkerOS event creation\n */\nfunction processEvent(\n push: Collector.PushFn,\n settings: { prefix?: string; filter?: (event: unknown) => boolean } = {},\n rawEvent: unknown,\n): void {\n // Apply filter if provided\n if (settings.filter) {\n const filterFn = tryCatch(\n () => settings.filter!(rawEvent),\n () => false, // If filter throws, don't skip the event\n );\n const filterResult = filterFn();\n if (filterResult === true) {\n return; // Skip filtered events\n }\n }\n\n // Transform the event (handles gtag format and direct objects)\n const transformedEvent = transformDataLayerEvent(rawEvent);\n if (!transformedEvent) {\n return; // Skip invalid events\n }\n\n const prefix = settings.prefix || 'dataLayer';\n const eventName = `${prefix} ${transformedEvent.name}`;\n\n // Create partial WalkerOS event structure (collector will enrich it)\n const { name: _name, ...data } = transformedEvent;\n const partialEvent: WalkerOS.DeepPartialEvent = {\n name: eventName,\n data: data as WalkerOS.Properties,\n };\n\n // Push to collector\n tryCatch(\n () => push(partialEvent),\n () => {}, // Silently handle push errors\n )();\n}\n\n/**\n * Transform dataLayer events to standardized format\n * Handles: gtag arguments, direct objects, existing events\n */\nfunction transformDataLayerEvent(\n rawEvent: unknown,\n): { name: string; [key: string]: unknown } | null {\n // Handle direct object format: { event: 'test', data: 'value' }\n if (isObject(rawEvent) && isString(rawEvent.event)) {\n const { event, ...rest } = rawEvent;\n return { name: event, ...rest };\n }\n\n // Handle gtag argument format: ['consent', 'update', { ad_storage: 'granted' }]\n if (isArray(rawEvent) && rawEvent.length >= 2) {\n return transformGtagArgs(rawEvent);\n }\n\n // Handle arguments object (from gtag function calls)\n if (isGtagArguments(rawEvent)) {\n const argsArray = Array.from(rawEvent as ArrayLike<unknown>);\n return transformGtagArgs(argsArray);\n }\n\n return null;\n}\n\n/**\n * Transform gtag-style arguments to event object\n * ['consent', 'update', { ad_storage: 'granted' }] → { event: 'consent update', ad_storage: 'granted' }\n */\nfunction transformGtagArgs(\n args: unknown[],\n): { name: string; [key: string]: unknown } | null {\n const [command, action, params] = args;\n\n if (!isString(command)) return null;\n\n let eventName: string;\n let eventData: Record<string, unknown> = {};\n\n switch (command) {\n case 'consent':\n // Consent requires action and params\n if (!isString(action) || args.length < 3) return null;\n // Only allow 'default' and 'update' actions for consent\n if (action !== 'default' && action !== 'update') return null;\n // Params must be a valid object (not null)\n if (!isObject(params) || params === null) return null;\n\n eventName = `${command} ${action}`;\n eventData = { ...params };\n break;\n\n case 'event':\n // Event requires at least action parameter\n if (!isString(action)) return null;\n eventName = action;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'config':\n // Config requires at least action parameter\n if (!isString(action)) return null;\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n break;\n\n case 'set':\n if (isString(action)) {\n eventName = `${command} ${action}`;\n if (isObject(params)) {\n eventData = { ...params };\n }\n } else if (isObject(action)) {\n eventName = `${command} custom`;\n eventData = { ...action };\n } else {\n return null;\n }\n break;\n\n default:\n // Unknown command, ignore\n return null;\n }\n\n return {\n name: eventName,\n ...eventData,\n };\n}\n\n/**\n * Check if object is gtag arguments object\n */\nfunction isGtagArguments(obj: unknown): boolean {\n return (\n obj != null &&\n typeof obj === 'object' &&\n 'length' in obj &&\n typeof (obj as ArrayLike<unknown>).length === 'number' &&\n (obj as ArrayLike<unknown>).length > 0\n );\n}\n","import type { WalkerOS, Source, Elb } from '@walkeros/core';\nimport type { SettingsSchema } from '../schemas';\nimport { z } from '@walkeros/core/dev';\n\ndeclare global {\n interface Window {\n dataLayer?: DataLayer;\n [key: string]: DataLayer | unknown;\n }\n}\n\nexport type DataLayer = Array<unknown>;\n\n// Base settings from Zod schema\ntype BaseSettings = z.infer<typeof SettingsSchema>;\n\n// Override filter to be actual function type (not serializable in schema)\nexport interface Settings extends Omit<BaseSettings, 'filter'> {\n name?: string;\n prefix?: string;\n filter?: (event: unknown) => WalkerOS.PromiseOrValue<boolean>;\n}\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport type Push = Elb.Fn;\n\nexport interface Env extends Source.BaseEnv {\n window?: Window & typeof globalThis;\n}\n\nexport type Types = Source.Types<Settings, Mapping, Push, Env, InitSettings>;\n\nexport type Config = Source.Config<Types>;\n\nexport type DataLayerEvent = {\n event: string;\n [key: string]: unknown;\n};\n\nexport type MappedEvent = {\n event?: WalkerOS.DeepPartialEvent & { id: string };\n command?: {\n name: string;\n data: unknown;\n };\n};\n","import type { Source, Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for dataLayer source\n *\n * These environments provide standardized mock structures for testing\n * dataLayer interception without requiring a real window object.\n */\n\n// Simple no-op function for mocking\nconst noop = () => {};\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopLogger: Logger.Instance = {\n error: noop,\n warn: noop,\n info: noop,\n debug: noop,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noop,\n scope: () => noopLogger,\n};\n\n/**\n * Environment interface for dataLayer source\n */\ninterface DataLayerEnv extends Source.BaseEnv {\n window?: typeof window;\n}\n\n/**\n * Mock window object with dataLayer array\n */\nconst createMockWindow = () => ({\n dataLayer: [] as unknown[],\n addEventListener: noop,\n removeEventListener: noop,\n});\n\n/**\n * Standard mock environment for testing dataLayer source\n *\n * Use this for testing dataLayer.push interception and event transformation\n * without requiring a real browser environment.\n */\nexport const push: DataLayerEnv = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n get window() {\n return createMockWindow() as unknown as typeof window;\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const gtagPurchase: Flow.StepExample = {\n in: [\n 'event',\n 'purchase',\n {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n ],\n out: {\n name: 'dataLayer purchase',\n data: {\n transaction_id: 'T-12345',\n value: 25.42,\n currency: 'EUR',\n items: [{ item_id: 'SKU-1', item_name: 'T-Shirt', quantity: 1 }],\n },\n entity: 'dataLayer',\n action: 'purchase',\n },\n};\n\nexport const consentUpdate: Flow.StepExample = {\n in: [\n 'consent',\n 'update',\n {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n ],\n out: {\n name: 'dataLayer consent update',\n data: {\n ad_storage: 'granted',\n analytics_storage: 'granted',\n },\n entity: 'dataLayer',\n action: 'consent update',\n },\n};\n\nexport const gtagAddToCart: Flow.StepExample = {\n in: [\n 'event',\n 'add_to_cart',\n {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n ],\n out: {\n name: 'dataLayer add_to_cart',\n data: {\n currency: 'EUR',\n value: 15.25,\n items: [\n {\n item_id: 'SKU_12345',\n item_name: 'T-Shirt',\n item_variant: 'red',\n quantity: 1,\n price: 15.25,\n },\n ],\n },\n entity: 'dataLayer',\n action: 'add_to_cart',\n },\n};\n\nexport const gtagViewItem: Flow.StepExample = {\n in: [\n 'event',\n 'view_item',\n {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n ],\n out: {\n name: 'dataLayer view_item',\n data: {\n currency: 'EUR',\n value: 29.99,\n items: [\n {\n item_id: 'SKU_67890',\n item_name: 'Sneakers',\n item_category: 'Footwear',\n price: 29.99,\n },\n ],\n },\n entity: 'dataLayer',\n action: 'view_item',\n },\n};\n\nexport const directEvent: Flow.StepExample = {\n in: {\n event: 'custom_event',\n category: 'engagement',\n label: 'video_play',\n },\n out: {\n name: 'dataLayer custom_event',\n data: {\n category: 'engagement',\n label: 'video_play',\n },\n entity: 'dataLayer',\n action: 'custom_event',\n },\n};\n","import type { Source } from '@walkeros/core';\n\n/** Prepopulates window.dataLayer before source init. */\nexport const setup: Source.SetupFn = (input, env) => {\n const win = env.window as Window & { dataLayer?: unknown[] };\n if (!win.dataLayer) win.dataLayer = [];\n\n if (Array.isArray(input)) {\n for (const item of input) win.dataLayer.push(item);\n } else if (input && typeof input === 'object') {\n win.dataLayer.push(input);\n }\n};\n","import type { Source, On } from '@walkeros/core';\nimport type { Types } from './types';\nimport { interceptDataLayer, processExistingEvents } from './interceptor';\n\n// Export types for external usage\nexport * as SourceDataLayer from './types';\n\n// Export examples\nexport * from './examples';\n\n/**\n * DataLayer source implementation using environment injection.\n *\n * This source intercepts dataLayer.push calls and transforms them to WalkerOS events.\n * It works by replacing the dataLayer.push method with a custom handler.\n */\nexport const sourceDataLayer: Source.Init<Types> = async (context) => {\n const { config, env } = context;\n const { elb, window: envWindow } = env;\n\n const settings: Source.Settings<Types> = {\n name: 'dataLayer',\n prefix: 'dataLayer',\n ...config?.settings,\n };\n\n const fullConfig: Source.Config<Types> = {\n settings,\n };\n\n let pendingReplayCount = 0;\n\n if (envWindow) {\n // Snapshot how many items exist before interception\n const dataLayerName = settings.name || 'dataLayer';\n const dl = (envWindow as Record<string, unknown>)[dataLayerName];\n pendingReplayCount = Array.isArray(dl) ? dl.length : 0;\n\n const win = envWindow as unknown as Record<string, unknown>;\n\n // Set up interceptor immediately so no new events are missed\n interceptDataLayer(elb, fullConfig, win);\n\n if (context.collector.allowed && pendingReplayCount > 0) {\n // Collector already ran — process existing events immediately\n processExistingEvents(elb, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n }\n\n // Handle on-run to replay existing events (when source inits before run)\n const handleEvent = async (event: On.Types) => {\n if (event === 'run' && envWindow && pendingReplayCount > 0) {\n const win = envWindow as unknown as Record<string, unknown>;\n processExistingEvents(elb, fullConfig, pendingReplayCount, win);\n pendingReplayCount = 0;\n }\n };\n\n return {\n type: 'dataLayer',\n config: fullConfig,\n push: elb,\n on: handleEvent,\n destroy: async () => {\n // Cleanup: restore original dataLayer.push if possible\n const dataLayerName = settings.name || 'dataLayer';\n if (\n envWindow &&\n envWindow[dataLayerName] &&\n Array.isArray(envWindow[dataLayerName])\n ) {\n // Note: Complete restoration would require storing original push method\n // For now, we'll just document this limitation\n }\n },\n };\n};\n\nexport default sourceDataLayer;\n"],"mappings":"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","names":["push"]}
|
package/dist/walkerOS.json
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
"version": "2.1.1",
|
|
5
5
|
"type": "source",
|
|
6
6
|
"platform": "web",
|
|
7
|
-
"renderer": "codebox"
|
|
7
|
+
"renderer": "codebox",
|
|
8
|
+
"docs": "https://www.walkeros.io/docs/sources/web/datalayer",
|
|
9
|
+
"source": "https://github.com/elbwalker/walkerOS/tree/main/packages/web/sources/dataLayer/src"
|
|
8
10
|
},
|
|
9
11
|
"schemas": {
|
|
10
12
|
"settings": {
|
|
@@ -72,7 +74,7 @@
|
|
|
72
74
|
"$code": "()=>{}"
|
|
73
75
|
},
|
|
74
76
|
"scope": {
|
|
75
|
-
"$code": "()=>
|
|
77
|
+
"$code": "()=>_"
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
}
|
|
@@ -116,6 +118,43 @@
|
|
|
116
118
|
"action": "custom_event"
|
|
117
119
|
}
|
|
118
120
|
},
|
|
121
|
+
"gtagAddToCart": {
|
|
122
|
+
"in": [
|
|
123
|
+
"event",
|
|
124
|
+
"add_to_cart",
|
|
125
|
+
{
|
|
126
|
+
"currency": "EUR",
|
|
127
|
+
"value": 15.25,
|
|
128
|
+
"items": [
|
|
129
|
+
{
|
|
130
|
+
"item_id": "SKU_12345",
|
|
131
|
+
"item_name": "T-Shirt",
|
|
132
|
+
"item_variant": "red",
|
|
133
|
+
"quantity": 1,
|
|
134
|
+
"price": 15.25
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"out": {
|
|
140
|
+
"name": "dataLayer add_to_cart",
|
|
141
|
+
"data": {
|
|
142
|
+
"currency": "EUR",
|
|
143
|
+
"value": 15.25,
|
|
144
|
+
"items": [
|
|
145
|
+
{
|
|
146
|
+
"item_id": "SKU_12345",
|
|
147
|
+
"item_name": "T-Shirt",
|
|
148
|
+
"item_variant": "red",
|
|
149
|
+
"quantity": 1,
|
|
150
|
+
"price": 15.25
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
},
|
|
154
|
+
"entity": "dataLayer",
|
|
155
|
+
"action": "add_to_cart"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
119
158
|
"gtagPurchase": {
|
|
120
159
|
"in": [
|
|
121
160
|
"event",
|
|
@@ -150,6 +189,41 @@
|
|
|
150
189
|
"entity": "dataLayer",
|
|
151
190
|
"action": "purchase"
|
|
152
191
|
}
|
|
192
|
+
},
|
|
193
|
+
"gtagViewItem": {
|
|
194
|
+
"in": [
|
|
195
|
+
"event",
|
|
196
|
+
"view_item",
|
|
197
|
+
{
|
|
198
|
+
"currency": "EUR",
|
|
199
|
+
"value": 29.99,
|
|
200
|
+
"items": [
|
|
201
|
+
{
|
|
202
|
+
"item_id": "SKU_67890",
|
|
203
|
+
"item_name": "Sneakers",
|
|
204
|
+
"item_category": "Footwear",
|
|
205
|
+
"price": 29.99
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
"out": {
|
|
211
|
+
"name": "dataLayer view_item",
|
|
212
|
+
"data": {
|
|
213
|
+
"currency": "EUR",
|
|
214
|
+
"value": 29.99,
|
|
215
|
+
"items": [
|
|
216
|
+
{
|
|
217
|
+
"item_id": "SKU_67890",
|
|
218
|
+
"item_name": "Sneakers",
|
|
219
|
+
"item_category": "Footwear",
|
|
220
|
+
"price": 29.99
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
"entity": "dataLayer",
|
|
225
|
+
"action": "view_item"
|
|
226
|
+
}
|
|
153
227
|
}
|
|
154
228
|
}
|
|
155
229
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/web-source-datalayer",
|
|
3
3
|
"description": "DataLayer source for walkerOS",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.0",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"sideEffects": false,
|
|
7
6
|
"main": "./dist/index.js",
|
|
8
7
|
"module": "./dist/index.mjs",
|
|
9
8
|
"types": "./dist/index.d.ts",
|
|
@@ -37,8 +36,8 @@
|
|
|
37
36
|
"update": "npx npm-check-updates -u && npm update"
|
|
38
37
|
},
|
|
39
38
|
"dependencies": {
|
|
40
|
-
"@walkeros/core": "
|
|
41
|
-
"@walkeros/collector": "
|
|
39
|
+
"@walkeros/core": "^3.0.0",
|
|
40
|
+
"@walkeros/collector": "^3.0.0"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
43
|
"@types/gtag.js": "^0.0.20"
|
|
@@ -55,7 +54,8 @@
|
|
|
55
54
|
"walkerOS": {
|
|
56
55
|
"type": "source",
|
|
57
56
|
"platform": "web",
|
|
58
|
-
"renderer": "codebox"
|
|
57
|
+
"renderer": "codebox",
|
|
58
|
+
"docs": "https://www.walkeros.io/docs/sources/web/datalayer"
|
|
59
59
|
},
|
|
60
60
|
"keywords": [
|
|
61
61
|
"walkerOS",
|