@walkeros/server-destination-reddit 3.4.0-next-1776749829492

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/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # @walkeros/server-destination-reddit
2
+
3
+ Server-side Reddit Conversions API destination for walkerOS.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @walkeros/server-destination-reddit
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ ```json
14
+ {
15
+ "destinations": {
16
+ "reddit": {
17
+ "package": "@walkeros/server-destination-reddit",
18
+ "config": {
19
+ "settings": {
20
+ "accessToken": "rdt_...",
21
+ "pixelId": "a2_abcdef123456"
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ ## Settings
30
+
31
+ | Setting | Type | Required | Default | Description |
32
+ | --------------- | -------- | -------- | --------------------------------------------------------- | ---------------------------------------------------- |
33
+ | `accessToken` | string | yes | - | Reddit Conversion Access Token (Bearer auth) |
34
+ | `pixelId` | string | yes | - | Reddit Pixel ID (appended as API path) |
35
+ | `action_source` | string | no | - | Event source: `WEBSITE`, `APP`, `PHYSICAL_STORE` |
36
+ | `doNotHash` | string[] | no | - | User fields to skip hashing |
37
+ | `test_mode` | boolean | no | `false` | Enable test mode (top-level boolean in request body) |
38
+ | `url` | string | no | `https://ads-api.reddit.com/api/v2.0/conversions/events/` | Custom API base URL |
39
+ | `user_data` | object | no | - | Default user field mapping applied to all events |
40
+
41
+ ## Event Mapping
42
+
43
+ Reddit uses a rigid taxonomy. Map walkerOS events to a standard `tracking_type`:
44
+
45
+ | walkerOS Event | Reddit tracking_type |
46
+ | ------------------ | -------------------- |
47
+ | `page view` | `PageVisit` |
48
+ | `product view` | `ViewContent` |
49
+ | `site search` | `Search` |
50
+ | `product add` | `AddToCart` |
51
+ | `product wishlist` | `AddToWishlist` |
52
+ | `order complete` | `Purchase` |
53
+ | `form submit` | `Lead` |
54
+ | `user signup` | `SignUp` |
55
+
56
+ Any non-standard name becomes
57
+ `{ tracking_type: 'Custom', custom_event_name: '<name>' }` automatically.
58
+
59
+ ## User Data
60
+
61
+ ### Hashed Fields (SHA-256)
62
+
63
+ | Field | Key | Description |
64
+ | ----------- | ------------- | ------------------------------ |
65
+ | Email | `email` | Lowercase, trimmed |
66
+ | External ID | `external_id` | Advertiser user identifier |
67
+ | IP address | `ip_address` | Hashed (unlike Meta/Pinterest) |
68
+ | User agent | `user_agent` | Hashed (unlike Meta/Pinterest) |
69
+ | IDFA | `idfa` | iOS advertising identifier |
70
+ | AAID | `aaid` | Android advertising identifier |
71
+
72
+ ### Pass-through Fields (not hashed)
73
+
74
+ | Field | Key |
75
+ | ----------------- | ------------------------- |
76
+ | UUID | `uuid` |
77
+ | Opt-out | `opt_out` |
78
+ | Screen dimensions | `screen_dimensions` |
79
+ | Data processing | `data_processing_options` |
80
+
81
+ Use `doNotHash` to skip hashing for pre-hashed values.
82
+
83
+ ## event_metadata
84
+
85
+ Conversion details (value, currency, products, etc.) are nested under
86
+ `event_metadata` (Reddit's equivalent of Meta's `custom_data`). The destination
87
+ automatically sets `event_metadata.conversion_id` to `event.id` for
88
+ deduplication with the Reddit Pixel.
89
+
90
+ ```json
91
+ {
92
+ "data": {
93
+ "map": {
94
+ "event_metadata": {
95
+ "map": {
96
+ "value_decimal": "data.total",
97
+ "currency": { "key": "data.currency", "value": "USD" },
98
+ "item_count": { "value": 1 },
99
+ "products": {
100
+ "loop": [
101
+ "nested",
102
+ {
103
+ "condition": { "$code": "e => e.entity === 'product'" },
104
+ "map": {
105
+ "id": "data.id",
106
+ "name": "data.name",
107
+ "category": {
108
+ "key": "data.category",
109
+ "value": "uncategorized"
110
+ }
111
+ }
112
+ }
113
+ ]
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ ## Deduplication
123
+
124
+ The destination automatically sets `event_metadata.conversion_id` to `event.id`.
125
+ When the Reddit Pixel is also in the browser, deduplication works automatically
126
+ because both sides share the same walkerOS `event.id`.
127
+
128
+ ## Test Mode
129
+
130
+ Set `test_mode: true` in settings to send `"test_mode": true` in the request
131
+ body. This is a top-level boolean (not a query parameter). Events sent with
132
+ `test_mode` do not count toward ads delivery.
133
+
134
+ ## Links
135
+
136
+ - [Reddit Conversions API documentation](https://ads-api.reddit.com/docs/v2/#tag/Conversions-API)
137
+ - [walkerOS documentation](https://www.walkeros.io/docs/destinations/server/reddit)
package/dist/dev.d.mts ADDED
@@ -0,0 +1,115 @@
1
+ import * as _walkeros_core_dev from '@walkeros/core/dev';
2
+ import { z } from '@walkeros/core/dev';
3
+ import { DestinationServer, sendServer } from '@walkeros/server-core';
4
+ import { Flow } from '@walkeros/core';
5
+
6
+ /**
7
+ * Action Source Enum
8
+ * Where the conversion event took place
9
+ * https://ads-api.reddit.com/docs/v2/#tag/Conversions-API
10
+ */
11
+ declare const ActionSourceSchema: z.ZodEnum<{
12
+ WEBSITE: "WEBSITE";
13
+ APP: "APP";
14
+ PHYSICAL_STORE: "PHYSICAL_STORE";
15
+ }>;
16
+ /**
17
+ * Tracking Type
18
+ * Standard Reddit Conversions API event types.
19
+ * Custom events use `Custom` with a `custom_event_name`.
20
+ */
21
+ declare const TrackingTypeSchema: z.ZodEnum<{
22
+ PageVisit: "PageVisit";
23
+ ViewContent: "ViewContent";
24
+ Search: "Search";
25
+ AddToCart: "AddToCart";
26
+ AddToWishlist: "AddToWishlist";
27
+ Purchase: "Purchase";
28
+ Lead: "Lead";
29
+ SignUp: "SignUp";
30
+ Custom: "Custom";
31
+ }>;
32
+
33
+ declare const SettingsSchema: z.ZodObject<{
34
+ accessToken: z.ZodString;
35
+ pixelId: z.ZodString;
36
+ action_source: z.ZodOptional<z.ZodEnum<{
37
+ WEBSITE: "WEBSITE";
38
+ APP: "APP";
39
+ PHYSICAL_STORE: "PHYSICAL_STORE";
40
+ }>>;
41
+ doNotHash: z.ZodOptional<z.ZodArray<z.ZodString>>;
42
+ test_mode: z.ZodOptional<z.ZodBoolean>;
43
+ url: z.ZodOptional<z.ZodString>;
44
+ user_data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
45
+ }, z.core.$strip>;
46
+ type Settings = z.infer<typeof SettingsSchema>;
47
+
48
+ /**
49
+ * Reddit Conversions API Mapping Schema
50
+ * Reddit CAPI has no event-level mapping configuration
51
+ */
52
+ declare const MappingSchema: z.ZodObject<{}, z.core.$strip>;
53
+ /**
54
+ * Type inference from MappingSchema
55
+ */
56
+ type Mapping = z.infer<typeof MappingSchema>;
57
+
58
+ declare const settings: _walkeros_core_dev.JSONSchema;
59
+ declare const mapping: _walkeros_core_dev.JSONSchema;
60
+
61
+ declare const index$1_ActionSourceSchema: typeof ActionSourceSchema;
62
+ type index$1_Mapping = Mapping;
63
+ declare const index$1_MappingSchema: typeof MappingSchema;
64
+ type index$1_Settings = Settings;
65
+ declare const index$1_SettingsSchema: typeof SettingsSchema;
66
+ declare const index$1_TrackingTypeSchema: typeof TrackingTypeSchema;
67
+ declare const index$1_mapping: typeof mapping;
68
+ declare const index$1_settings: typeof settings;
69
+ declare namespace index$1 {
70
+ export { index$1_ActionSourceSchema as ActionSourceSchema, type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type index$1_Settings as Settings, index$1_SettingsSchema as SettingsSchema, index$1_TrackingTypeSchema as TrackingTypeSchema, index$1_mapping as mapping, index$1_settings as settings };
71
+ }
72
+
73
+ interface Env extends DestinationServer.Env {
74
+ sendServer?: typeof sendServer;
75
+ }
76
+
77
+ /**
78
+ * Standard mock environment for push operations
79
+ *
80
+ * Use this for testing Reddit Conversions API events without making
81
+ * actual HTTP requests to Reddit's servers.
82
+ */
83
+ declare const push: Env;
84
+ declare const simulation: string[];
85
+
86
+ declare const env_push: typeof push;
87
+ declare const env_simulation: typeof simulation;
88
+ declare namespace env {
89
+ export { env_push as push, env_simulation as simulation };
90
+ }
91
+
92
+ declare const purchase: Flow.StepExample;
93
+ declare const addToCart: Flow.StepExample;
94
+ declare const pageVisit: Flow.StepExample;
95
+ declare const lead: Flow.StepExample;
96
+ declare const signUp: Flow.StepExample;
97
+ declare const search: Flow.StepExample;
98
+
99
+ declare const step_addToCart: typeof addToCart;
100
+ declare const step_lead: typeof lead;
101
+ declare const step_pageVisit: typeof pageVisit;
102
+ declare const step_purchase: typeof purchase;
103
+ declare const step_search: typeof search;
104
+ declare const step_signUp: typeof signUp;
105
+ declare namespace step {
106
+ export { step_addToCart as addToCart, step_lead as lead, step_pageVisit as pageVisit, step_purchase as purchase, step_search as search, step_signUp as signUp };
107
+ }
108
+
109
+ declare const index_env: typeof env;
110
+ declare const index_step: typeof step;
111
+ declare namespace index {
112
+ export { index_env as env, index_step as step };
113
+ }
114
+
115
+ export { index as examples, index$1 as schemas };
package/dist/dev.d.ts ADDED
@@ -0,0 +1,115 @@
1
+ import * as _walkeros_core_dev from '@walkeros/core/dev';
2
+ import { z } from '@walkeros/core/dev';
3
+ import { DestinationServer, sendServer } from '@walkeros/server-core';
4
+ import { Flow } from '@walkeros/core';
5
+
6
+ /**
7
+ * Action Source Enum
8
+ * Where the conversion event took place
9
+ * https://ads-api.reddit.com/docs/v2/#tag/Conversions-API
10
+ */
11
+ declare const ActionSourceSchema: z.ZodEnum<{
12
+ WEBSITE: "WEBSITE";
13
+ APP: "APP";
14
+ PHYSICAL_STORE: "PHYSICAL_STORE";
15
+ }>;
16
+ /**
17
+ * Tracking Type
18
+ * Standard Reddit Conversions API event types.
19
+ * Custom events use `Custom` with a `custom_event_name`.
20
+ */
21
+ declare const TrackingTypeSchema: z.ZodEnum<{
22
+ PageVisit: "PageVisit";
23
+ ViewContent: "ViewContent";
24
+ Search: "Search";
25
+ AddToCart: "AddToCart";
26
+ AddToWishlist: "AddToWishlist";
27
+ Purchase: "Purchase";
28
+ Lead: "Lead";
29
+ SignUp: "SignUp";
30
+ Custom: "Custom";
31
+ }>;
32
+
33
+ declare const SettingsSchema: z.ZodObject<{
34
+ accessToken: z.ZodString;
35
+ pixelId: z.ZodString;
36
+ action_source: z.ZodOptional<z.ZodEnum<{
37
+ WEBSITE: "WEBSITE";
38
+ APP: "APP";
39
+ PHYSICAL_STORE: "PHYSICAL_STORE";
40
+ }>>;
41
+ doNotHash: z.ZodOptional<z.ZodArray<z.ZodString>>;
42
+ test_mode: z.ZodOptional<z.ZodBoolean>;
43
+ url: z.ZodOptional<z.ZodString>;
44
+ user_data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
45
+ }, z.core.$strip>;
46
+ type Settings = z.infer<typeof SettingsSchema>;
47
+
48
+ /**
49
+ * Reddit Conversions API Mapping Schema
50
+ * Reddit CAPI has no event-level mapping configuration
51
+ */
52
+ declare const MappingSchema: z.ZodObject<{}, z.core.$strip>;
53
+ /**
54
+ * Type inference from MappingSchema
55
+ */
56
+ type Mapping = z.infer<typeof MappingSchema>;
57
+
58
+ declare const settings: _walkeros_core_dev.JSONSchema;
59
+ declare const mapping: _walkeros_core_dev.JSONSchema;
60
+
61
+ declare const index$1_ActionSourceSchema: typeof ActionSourceSchema;
62
+ type index$1_Mapping = Mapping;
63
+ declare const index$1_MappingSchema: typeof MappingSchema;
64
+ type index$1_Settings = Settings;
65
+ declare const index$1_SettingsSchema: typeof SettingsSchema;
66
+ declare const index$1_TrackingTypeSchema: typeof TrackingTypeSchema;
67
+ declare const index$1_mapping: typeof mapping;
68
+ declare const index$1_settings: typeof settings;
69
+ declare namespace index$1 {
70
+ export { index$1_ActionSourceSchema as ActionSourceSchema, type index$1_Mapping as Mapping, index$1_MappingSchema as MappingSchema, type index$1_Settings as Settings, index$1_SettingsSchema as SettingsSchema, index$1_TrackingTypeSchema as TrackingTypeSchema, index$1_mapping as mapping, index$1_settings as settings };
71
+ }
72
+
73
+ interface Env extends DestinationServer.Env {
74
+ sendServer?: typeof sendServer;
75
+ }
76
+
77
+ /**
78
+ * Standard mock environment for push operations
79
+ *
80
+ * Use this for testing Reddit Conversions API events without making
81
+ * actual HTTP requests to Reddit's servers.
82
+ */
83
+ declare const push: Env;
84
+ declare const simulation: string[];
85
+
86
+ declare const env_push: typeof push;
87
+ declare const env_simulation: typeof simulation;
88
+ declare namespace env {
89
+ export { env_push as push, env_simulation as simulation };
90
+ }
91
+
92
+ declare const purchase: Flow.StepExample;
93
+ declare const addToCart: Flow.StepExample;
94
+ declare const pageVisit: Flow.StepExample;
95
+ declare const lead: Flow.StepExample;
96
+ declare const signUp: Flow.StepExample;
97
+ declare const search: Flow.StepExample;
98
+
99
+ declare const step_addToCart: typeof addToCart;
100
+ declare const step_lead: typeof lead;
101
+ declare const step_pageVisit: typeof pageVisit;
102
+ declare const step_purchase: typeof purchase;
103
+ declare const step_search: typeof search;
104
+ declare const step_signUp: typeof signUp;
105
+ declare namespace step {
106
+ export { step_addToCart as addToCart, step_lead as lead, step_pageVisit as pageVisit, step_purchase as purchase, step_search as search, step_signUp as signUp };
107
+ }
108
+
109
+ declare const index_env: typeof env;
110
+ declare const index_step: typeof step;
111
+ declare namespace index {
112
+ export { index_env as env, index_step as step };
113
+ }
114
+
115
+ export { index as examples, index$1 as schemas };
package/dist/dev.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,n=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},s={};n(s,{examples:()=>y,schemas:()=>d}),module.exports=(e=s,((e,n,s,d)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let o of r(n))i.call(e,o)||o===s||t(e,o,{get:()=>n[o],enumerable:!(d=a(n,o))||d.enumerable});return e})(t({},"__esModule",{value:!0}),e));var d={};n(d,{ActionSourceSchema:()=>u,MappingSchema:()=>l,SettingsSchema:()=>v,TrackingTypeSchema:()=>m,mapping:()=>g,settings:()=>_});var o=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),p=require("@walkeros/core/dev"),u=p.z.enum(["WEBSITE","APP","PHYSICAL_STORE"]),m=p.z.enum(["PageVisit","ViewContent","Search","AddToCart","AddToWishlist","Purchase","Lead","SignUp","Custom"]),v=c.z.object({accessToken:c.z.string().min(1).describe("Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)"),pixelId:c.z.string().min(1).describe("Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)"),action_source:u.describe("Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)").optional(),doNotHash:c.z.array(c.z.string()).describe("Array of user fields that should not be hashed (like ['email'])").optional(),test_mode:c.z.boolean().describe("Enable test mode by sending test_mode: true in the request body (like true)").optional(),url:c.z.string().url().describe("Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)").optional(),user_data:c.z.record(c.z.string(),c.z.string()).describe("Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })").optional()}),l=require("@walkeros/core/dev").z.object({}),_=(0,o.zodToSchema)(v),g=(0,o.zodToSchema)(l),y={};n(y,{env:()=>f,step:()=>S});var f={};n(f,{push:()=>b,simulation:()=>h});var b={sendServer:async()=>({ok:!0,data:{success:!0}})},h=["sendServer"],S={};n(S,{addToCart:()=>P,lead:()=>O,pageVisit:()=>z,purchase:()=>T,search:()=>A,signUp:()=>x});var k=require("@walkeros/core"),w="https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",E={headers:{Authorization:"Bearer s3cr3t"}},T={in:(0,k.getEvent)("order complete",{timestamp:1700000900,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Everyday Ruck Snack",category:"bags",price:"129.99",quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"server",id:"https://shop.example.com",previous_id:""}}),mapping:{name:"Purchase",data:{map:{event_metadata:{map:{value_decimal:"data.total",currency:{key:"data.currency",value:"EUR"},item_count:{fn:e=>e.nested.filter(e=>"product"===e.entity).length},products:{loop:["nested",{condition:e=>(0,k.isObject)(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",category:{key:"data.category",value:"uncategorized"}}}]}}}}}},out:[["sendServer",w,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.900Z",event_at_ms:1700000900,event_type:{tracking_type:"Purchase"},user:{},event_metadata:{conversion_id:"1700000900-gr0up-1",value_decimal:249.99,currency:"EUR",item_count:1,products:[{id:"SKU-A1",name:"Everyday Ruck Snack",category:"bags"}]}}]}}),E]]},P={in:(0,k.getEvent)("product add",{timestamp:1700000901,data:{id:"SKU-B2",name:"Cool Cap",category:"hats",price:"42.00",quantity:1},user:{id:"user-456"},source:{type:"server",id:"https://shop.example.com/products",previous_id:""}}),mapping:{name:"AddToCart",data:{map:{event_metadata:{map:{value_decimal:"data.price",currency:{value:"EUR"},item_count:{value:1},products:{set:[{map:{id:"data.id",name:"data.name",category:{key:"data.category",value:"uncategorized"}}}]}}}}}},out:[["sendServer",w,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.901Z",event_at_ms:1700000901,event_type:{tracking_type:"AddToCart"},user:{},event_metadata:{conversion_id:"1700000901-gr0up-1",value_decimal:"42.00",currency:"EUR",item_count:1,products:[{id:"SKU-B2",name:"Cool Cap",category:"hats"}]}}]}}),E]]},z={in:(0,k.getEvent)("page view",{timestamp:1700000902,user:{id:"user-789"},source:{type:"server",id:"https://www.example.com/docs/",previous_id:""}}),mapping:{name:"PageVisit"},out:[["sendServer",w,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.902Z",event_at_ms:1700000902,event_type:{tracking_type:"PageVisit"},user:{},event_metadata:{conversion_id:"1700000902-gr0up-1"}}]}}),E]]},O={in:(0,k.getEvent)("form submit",{timestamp:1700000903,data:{form:"contact"},user:{id:"user-lead-1",email:"lead@example.com"},source:{type:"server",id:"https://www.example.com/contact",previous_id:""}}),mapping:{name:"Lead",data:{map:{user:{map:{email:"user.email",external_id:"user.id"}}}}},out:[["sendServer",w,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.903Z",event_at_ms:1700000903,event_type:{tracking_type:"Lead"},user:{email:"9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2",external_id:"ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8"},event_metadata:{conversion_id:"1700000903-gr0up-1"}}]}}),E]]},x={in:(0,k.getEvent)("user signup",{timestamp:1700000904,data:{method:"email"},user:{id:"new-user-1",email:"new@example.com"},source:{type:"server",id:"https://www.example.com/register",previous_id:""}}),mapping:{name:"SignUp",data:{map:{user:{map:{email:"user.email",external_id:"user.id"}}}}},out:[["sendServer",w,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.904Z",event_at_ms:1700000904,event_type:{tracking_type:"SignUp"},user:{email:"f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716",external_id:"b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde"},event_metadata:{conversion_id:"1700000904-gr0up-1"}}]}}),E]]},A={in:(0,k.getEvent)("site search",{timestamp:1700000905,data:{query:"walkerOS destinations"},user:{id:"user-101"},source:{type:"server",id:"https://www.example.com/search",previous_id:""}}),mapping:{name:"Search",data:{map:{event_metadata:{map:{item_count:{value:1}}}}}},out:[["sendServer",w,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.905Z",event_at_ms:1700000905,event_type:{tracking_type:"Search"},user:{},event_metadata:{conversion_id:"1700000905-gr0up-1",item_count:1}}]}}),E]]};//# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { ActionSourceSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)',\n ),\n pixelId: z\n .string()\n .min(1)\n .describe(\n 'Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)',\n ),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"Array of user fields that should not be hashed (like ['email'])\")\n .optional(),\n test_mode: z\n .boolean()\n .describe(\n 'Enable test mode by sending test_mode: true in the request body (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Action Source Enum\n * Where the conversion event took place\n * https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n */\nexport const ActionSourceSchema = z.enum(['WEBSITE', 'APP', 'PHYSICAL_STORE']);\n\n/**\n * Tracking Type\n * Standard Reddit Conversions API event types.\n * Custom events use `Custom` with a `custom_event_name`.\n */\nexport const TrackingTypeSchema = z.enum([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Reddit Conversions API Mapping Schema\n * Reddit CAPI has no event-level mapping configuration\n */\nexport const MappingSchema = z.object({});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for Reddit Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nconst mockSendServer: MockSendServer = async () => {\n // Simulate successful Reddit API response\n return {\n ok: true,\n data: {\n success: true,\n },\n };\n};\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Reddit Conversions API events without making\n * actual HTTP requests to Reddit's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Reddit Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.pixelId}` and\n * `body = { data: { events: [hashedServerEvent] } }`.\n *\n * Test fixture pins `pixelId = 'a2_abcdef123456'` and the default url, so\n * every endpoint resolves to:\n * https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456\n *\n * The serverEvent keys are assembled in this order (insertion order matters\n * for `JSON.stringify` string equality):\n * 1. event_at (ISO timestamp)\n * 2. event_at_ms\n * 3. event_type ({ tracking_type, custom_event_name? })\n * 4. ...restEventData (mapped event data minus user/event_metadata/click_id)\n * 5. user (hashed — email, external_id, ip_address, user_agent, idfa, aaid)\n * 6. event_metadata (conversion_id first, then merged metadata)\n * 7. click_id (only when a string is present)\n *\n * `options` carries the Authorization: Bearer <accessToken> header.\n */\nconst ENDPOINT =\n 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const purchase: Flow.StepExample = {\n in: getEvent('order complete', {\n timestamp: 1700000900,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: { type: 'server', id: 'https://shop.example.com', previous_id: '' },\n }),\n mapping: {\n name: 'Purchase',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n item_count: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n products: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.900Z',\n event_at_ms: 1700000900,\n event_type: { tracking_type: 'Purchase' },\n user: {},\n event_metadata: {\n conversion_id: '1700000900-gr0up-1',\n value_decimal: 249.99,\n currency: 'EUR',\n item_count: 1,\n products: [\n {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n in: getEvent('product add', {\n timestamp: 1700000901,\n data: {\n id: 'SKU-B2',\n name: 'Cool Cap',\n category: 'hats',\n price: '42.00',\n quantity: 1,\n },\n user: { id: 'user-456' },\n source: {\n type: 'server',\n id: 'https://shop.example.com/products',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'AddToCart',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.price',\n currency: { value: 'EUR' },\n item_count: { value: 1 },\n products: {\n set: [\n {\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.901Z',\n event_at_ms: 1700000901,\n event_type: { tracking_type: 'AddToCart' },\n user: {},\n event_metadata: {\n conversion_id: '1700000901-gr0up-1',\n value_decimal: '42.00',\n currency: 'EUR',\n item_count: 1,\n products: [\n { id: 'SKU-B2', name: 'Cool Cap', category: 'hats' },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n in: getEvent('page view', {\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: {\n type: 'server',\n id: 'https://www.example.com/docs/',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'PageVisit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.902Z',\n event_at_ms: 1700000902,\n event_type: { tracking_type: 'PageVisit' },\n user: {},\n event_metadata: { conversion_id: '1700000902-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n in: getEvent('form submit', {\n timestamp: 1700000903,\n data: { form: 'contact' },\n user: { id: 'user-lead-1', email: 'lead@example.com' },\n source: {\n type: 'server',\n id: 'https://www.example.com/contact',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'Lead',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.903Z',\n event_at_ms: 1700000903,\n event_type: { tracking_type: 'Lead' },\n user: {\n // sha256('lead@example.com')\n email:\n '9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2',\n // sha256('user-lead-1')\n external_id:\n 'ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8',\n },\n event_metadata: { conversion_id: '1700000903-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signUp: Flow.StepExample = {\n in: getEvent('user signup', {\n timestamp: 1700000904,\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: {\n type: 'server',\n id: 'https://www.example.com/register',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'SignUp',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.904Z',\n event_at_ms: 1700000904,\n event_type: { tracking_type: 'SignUp' },\n user: {\n // sha256('new@example.com')\n email:\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n // sha256('new-user-1')\n external_id:\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n },\n event_metadata: { conversion_id: '1700000904-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n in: getEvent('site search', {\n timestamp: 1700000905,\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: {\n type: 'server',\n id: 'https://www.example.com/search',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n event_metadata: {\n map: {\n item_count: { value: 1 },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.905Z',\n event_at_ms: 1700000905,\n event_type: { tracking_type: 'Search' },\n user: {},\n event_metadata: {\n conversion_id: '1700000905-gr0up-1',\n item_count: 1,\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["import_dev","import_dev","import_dev"]}
package/dist/dev.mjs ADDED
@@ -0,0 +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,{ActionSourceSchema:()=>n,MappingSchema:()=>m,SettingsSchema:()=>o,TrackingTypeSchema:()=>d,mapping:()=>u,settings:()=>p});import{zodToSchema as r}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";var n=s.enum(["WEBSITE","APP","PHYSICAL_STORE"]),d=s.enum(["PageVisit","ViewContent","Search","AddToCart","AddToWishlist","Purchase","Lead","SignUp","Custom"]),o=i.object({accessToken:i.string().min(1).describe("Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)"),pixelId:i.string().min(1).describe("Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)"),action_source:n.describe("Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)").optional(),doNotHash:i.array(i.string()).describe("Array of user fields that should not be hashed (like ['email'])").optional(),test_mode:i.boolean().describe("Enable test mode by sending test_mode: true in the request body (like true)").optional(),url:i.string().url().describe("Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)").optional(),user_data:i.record(i.string(),i.string()).describe("Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })").optional()});import{z as c}from"@walkeros/core/dev";var m=c.object({}),p=r(o),u=r(m),v={};a(v,{env:()=>l,step:()=>y});var l={};a(l,{push:()=>_,simulation:()=>g});var _={sendServer:async()=>({ok:!0,data:{success:!0}})},g=["sendServer"],y={};a(y,{addToCart:()=>w,lead:()=>x,pageVisit:()=>T,purchase:()=>k,search:()=>C,signUp:()=>A});import{getEvent as f,isObject as h}from"@walkeros/core";var S="https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456",b={headers:{Authorization:"Bearer s3cr3t"}},k={in:f("order complete",{timestamp:1700000900,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Everyday Ruck Snack",category:"bags",price:"129.99",quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"server",id:"https://shop.example.com",previous_id:""}}),mapping:{name:"Purchase",data:{map:{event_metadata:{map:{value_decimal:"data.total",currency:{key:"data.currency",value:"EUR"},item_count:{fn:e=>e.nested.filter(e=>"product"===e.entity).length},products:{loop:["nested",{condition:e=>h(e)&&"product"===e.entity,map:{id:"data.id",name:"data.name",category:{key:"data.category",value:"uncategorized"}}}]}}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.900Z",event_at_ms:1700000900,event_type:{tracking_type:"Purchase"},user:{},event_metadata:{conversion_id:"1700000900-gr0up-1",value_decimal:249.99,currency:"EUR",item_count:1,products:[{id:"SKU-A1",name:"Everyday Ruck Snack",category:"bags"}]}}]}}),b]]},w={in:f("product add",{timestamp:1700000901,data:{id:"SKU-B2",name:"Cool Cap",category:"hats",price:"42.00",quantity:1},user:{id:"user-456"},source:{type:"server",id:"https://shop.example.com/products",previous_id:""}}),mapping:{name:"AddToCart",data:{map:{event_metadata:{map:{value_decimal:"data.price",currency:{value:"EUR"},item_count:{value:1},products:{set:[{map:{id:"data.id",name:"data.name",category:{key:"data.category",value:"uncategorized"}}}]}}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.901Z",event_at_ms:1700000901,event_type:{tracking_type:"AddToCart"},user:{},event_metadata:{conversion_id:"1700000901-gr0up-1",value_decimal:"42.00",currency:"EUR",item_count:1,products:[{id:"SKU-B2",name:"Cool Cap",category:"hats"}]}}]}}),b]]},T={in:f("page view",{timestamp:1700000902,user:{id:"user-789"},source:{type:"server",id:"https://www.example.com/docs/",previous_id:""}}),mapping:{name:"PageVisit"},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.902Z",event_at_ms:1700000902,event_type:{tracking_type:"PageVisit"},user:{},event_metadata:{conversion_id:"1700000902-gr0up-1"}}]}}),b]]},x={in:f("form submit",{timestamp:1700000903,data:{form:"contact"},user:{id:"user-lead-1",email:"lead@example.com"},source:{type:"server",id:"https://www.example.com/contact",previous_id:""}}),mapping:{name:"Lead",data:{map:{user:{map:{email:"user.email",external_id:"user.id"}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.903Z",event_at_ms:1700000903,event_type:{tracking_type:"Lead"},user:{email:"9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2",external_id:"ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8"},event_metadata:{conversion_id:"1700000903-gr0up-1"}}]}}),b]]},A={in:f("user signup",{timestamp:1700000904,data:{method:"email"},user:{id:"new-user-1",email:"new@example.com"},source:{type:"server",id:"https://www.example.com/register",previous_id:""}}),mapping:{name:"SignUp",data:{map:{user:{map:{email:"user.email",external_id:"user.id"}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.904Z",event_at_ms:1700000904,event_type:{tracking_type:"SignUp"},user:{email:"f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716",external_id:"b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde"},event_metadata:{conversion_id:"1700000904-gr0up-1"}}]}}),b]]},C={in:f("site search",{timestamp:1700000905,data:{query:"walkerOS destinations"},user:{id:"user-101"},source:{type:"server",id:"https://www.example.com/search",previous_id:""}}),mapping:{name:"Search",data:{map:{event_metadata:{map:{item_count:{value:1}}}}}},out:[["sendServer",S,JSON.stringify({data:{events:[{event_at:"1970-01-20T16:13:20.905Z",event_at_ms:1700000905,event_type:{tracking_type:"Search"},user:{},event_metadata:{conversion_id:"1700000905-gr0up-1",item_count:1}}]}}),b]]};export{v as examples,t as schemas};//# sourceMappingURL=dev.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/primitives.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport * from './primitives';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\nimport { ActionSourceSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Reddit Conversion Access Token for Bearer authentication (like rdt_ABC123...)',\n ),\n pixelId: z\n .string()\n .min(1)\n .describe(\n 'Reddit Pixel ID used as the API path parameter (like a2_abcdef123456)',\n ),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (WEBSITE, APP, PHYSICAL_STORE) (like WEBSITE)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\"Array of user fields that should not be hashed (like ['email'])\")\n .optional(),\n test_mode: z\n .boolean()\n .describe(\n 'Enable test mode by sending test_mode: true in the request body (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Reddit Conversions API endpoint (like https://ads-api.reddit.com/api/v2.0/conversions/events/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user fields (like { email: 'user.email', external_id: 'user.id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Action Source Enum\n * Where the conversion event took place\n * https://ads-api.reddit.com/docs/v2/#tag/Conversions-API\n */\nexport const ActionSourceSchema = z.enum(['WEBSITE', 'APP', 'PHYSICAL_STORE']);\n\n/**\n * Tracking Type\n * Standard Reddit Conversions API event types.\n * Custom events use `Custom` with a `custom_event_name`.\n */\nexport const TrackingTypeSchema = z.enum([\n 'PageVisit',\n 'ViewContent',\n 'Search',\n 'AddToCart',\n 'AddToWishlist',\n 'Purchase',\n 'Lead',\n 'SignUp',\n 'Custom',\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Reddit Conversions API Mapping Schema\n * Reddit CAPI has no event-level mapping configuration\n */\nexport const MappingSchema = z.object({});\n\n/**\n * Type inference from MappingSchema\n */\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { SendDataValue, SendResponse } from '@walkeros/core';\nimport type { SendServerOptions } from '@walkeros/server-core';\nimport type { Env } from '../types';\n\n/**\n * Example environment configurations for Reddit Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\ntype MockSendServer = (\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n) => Promise<SendResponse>;\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nconst mockSendServer: MockSendServer = async () => {\n // Simulate successful Reddit API response\n return {\n ok: true,\n data: {\n success: true,\n },\n };\n};\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Reddit Conversions API events without making\n * actual HTTP requests to Reddit's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent, isObject } from '@walkeros/core';\n\n/**\n * Reddit Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * `endpoint = ${settings.url}${settings.pixelId}` and\n * `body = { data: { events: [hashedServerEvent] } }`.\n *\n * Test fixture pins `pixelId = 'a2_abcdef123456'` and the default url, so\n * every endpoint resolves to:\n * https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456\n *\n * The serverEvent keys are assembled in this order (insertion order matters\n * for `JSON.stringify` string equality):\n * 1. event_at (ISO timestamp)\n * 2. event_at_ms\n * 3. event_type ({ tracking_type, custom_event_name? })\n * 4. ...restEventData (mapped event data minus user/event_metadata/click_id)\n * 5. user (hashed — email, external_id, ip_address, user_agent, idfa, aaid)\n * 6. event_metadata (conversion_id first, then merged metadata)\n * 7. click_id (only when a string is present)\n *\n * `options` carries the Authorization: Bearer <accessToken> header.\n */\nconst ENDPOINT =\n 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_abcdef123456';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const purchase: Flow.StepExample = {\n in: getEvent('order complete', {\n timestamp: 1700000900,\n data: { id: 'ORD-300', total: 249.99, currency: 'EUR' },\n nested: [\n {\n entity: 'product',\n data: {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: { type: 'server', id: 'https://shop.example.com', previous_id: '' },\n }),\n mapping: {\n name: 'Purchase',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n item_count: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n products: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.900Z',\n event_at_ms: 1700000900,\n event_type: { tracking_type: 'Purchase' },\n user: {},\n event_metadata: {\n conversion_id: '1700000900-gr0up-1',\n value_decimal: 249.99,\n currency: 'EUR',\n item_count: 1,\n products: [\n {\n id: 'SKU-A1',\n name: 'Everyday Ruck Snack',\n category: 'bags',\n },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n in: getEvent('product add', {\n timestamp: 1700000901,\n data: {\n id: 'SKU-B2',\n name: 'Cool Cap',\n category: 'hats',\n price: '42.00',\n quantity: 1,\n },\n user: { id: 'user-456' },\n source: {\n type: 'server',\n id: 'https://shop.example.com/products',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'AddToCart',\n data: {\n map: {\n event_metadata: {\n map: {\n value_decimal: 'data.price',\n currency: { value: 'EUR' },\n item_count: { value: 1 },\n products: {\n set: [\n {\n map: {\n id: 'data.id',\n name: 'data.name',\n category: { key: 'data.category', value: 'uncategorized' },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.901Z',\n event_at_ms: 1700000901,\n event_type: { tracking_type: 'AddToCart' },\n user: {},\n event_metadata: {\n conversion_id: '1700000901-gr0up-1',\n value_decimal: '42.00',\n currency: 'EUR',\n item_count: 1,\n products: [\n { id: 'SKU-B2', name: 'Cool Cap', category: 'hats' },\n ],\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n in: getEvent('page view', {\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: {\n type: 'server',\n id: 'https://www.example.com/docs/',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'PageVisit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.902Z',\n event_at_ms: 1700000902,\n event_type: { tracking_type: 'PageVisit' },\n user: {},\n event_metadata: { conversion_id: '1700000902-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n in: getEvent('form submit', {\n timestamp: 1700000903,\n data: { form: 'contact' },\n user: { id: 'user-lead-1', email: 'lead@example.com' },\n source: {\n type: 'server',\n id: 'https://www.example.com/contact',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'Lead',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.903Z',\n event_at_ms: 1700000903,\n event_type: { tracking_type: 'Lead' },\n user: {\n // sha256('lead@example.com')\n email:\n '9fbdefe2837a03c9225be80e741f316f4d174d1732b719b6abb6477efc1ae9d2',\n // sha256('user-lead-1')\n external_id:\n 'ee818eebb052cf288ffeeb2e09ee35c9946e1a7f53a959cb3ef06d5d4adb78e8',\n },\n event_metadata: { conversion_id: '1700000903-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signUp: Flow.StepExample = {\n in: getEvent('user signup', {\n timestamp: 1700000904,\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: {\n type: 'server',\n id: 'https://www.example.com/register',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'SignUp',\n data: {\n map: {\n user: {\n map: {\n email: 'user.email',\n external_id: 'user.id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.904Z',\n event_at_ms: 1700000904,\n event_type: { tracking_type: 'SignUp' },\n user: {\n // sha256('new@example.com')\n email:\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n // sha256('new-user-1')\n external_id:\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n },\n event_metadata: { conversion_id: '1700000904-gr0up-1' },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n in: getEvent('site search', {\n timestamp: 1700000905,\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: {\n type: 'server',\n id: 'https://www.example.com/search',\n previous_id: '',\n },\n }),\n mapping: {\n name: 'Search',\n data: {\n map: {\n event_metadata: {\n map: {\n item_count: { value: 1 },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: {\n events: [\n {\n event_at: '1970-01-20T16:13:20.905Z',\n event_at_ms: 1700000905,\n event_type: { tracking_type: 'Search' },\n user: {},\n event_metadata: {\n conversion_id: '1700000905-gr0up-1',\n item_count: 1,\n },\n },\n ],\n },\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["z","z","z"]}
@@ -0,0 +1,40 @@
1
+ import { DestinationServer, sendServer } from '@walkeros/server-core';
2
+ import { Flow } from '@walkeros/core';
3
+
4
+ interface Env extends DestinationServer.Env {
5
+ sendServer?: typeof sendServer;
6
+ }
7
+
8
+ /**
9
+ * Standard mock environment for push operations
10
+ *
11
+ * Use this for testing Reddit Conversions API events without making
12
+ * actual HTTP requests to Reddit's servers.
13
+ */
14
+ declare const push: Env;
15
+ declare const simulation: string[];
16
+
17
+ declare const env_push: typeof push;
18
+ declare const env_simulation: typeof simulation;
19
+ declare namespace env {
20
+ export { env_push as push, env_simulation as simulation };
21
+ }
22
+
23
+ declare const purchase: Flow.StepExample;
24
+ declare const addToCart: Flow.StepExample;
25
+ declare const pageVisit: Flow.StepExample;
26
+ declare const lead: Flow.StepExample;
27
+ declare const signUp: Flow.StepExample;
28
+ declare const search: Flow.StepExample;
29
+
30
+ declare const step_addToCart: typeof addToCart;
31
+ declare const step_lead: typeof lead;
32
+ declare const step_pageVisit: typeof pageVisit;
33
+ declare const step_purchase: typeof purchase;
34
+ declare const step_search: typeof search;
35
+ declare const step_signUp: typeof signUp;
36
+ declare namespace step {
37
+ export { step_addToCart as addToCart, step_lead as lead, step_pageVisit as pageVisit, step_purchase as purchase, step_search as search, step_signUp as signUp };
38
+ }
39
+
40
+ export { env, step };
@@ -0,0 +1,40 @@
1
+ import { DestinationServer, sendServer } from '@walkeros/server-core';
2
+ import { Flow } from '@walkeros/core';
3
+
4
+ interface Env extends DestinationServer.Env {
5
+ sendServer?: typeof sendServer;
6
+ }
7
+
8
+ /**
9
+ * Standard mock environment for push operations
10
+ *
11
+ * Use this for testing Reddit Conversions API events without making
12
+ * actual HTTP requests to Reddit's servers.
13
+ */
14
+ declare const push: Env;
15
+ declare const simulation: string[];
16
+
17
+ declare const env_push: typeof push;
18
+ declare const env_simulation: typeof simulation;
19
+ declare namespace env {
20
+ export { env_push as push, env_simulation as simulation };
21
+ }
22
+
23
+ declare const purchase: Flow.StepExample;
24
+ declare const addToCart: Flow.StepExample;
25
+ declare const pageVisit: Flow.StepExample;
26
+ declare const lead: Flow.StepExample;
27
+ declare const signUp: Flow.StepExample;
28
+ declare const search: Flow.StepExample;
29
+
30
+ declare const step_addToCart: typeof addToCart;
31
+ declare const step_lead: typeof lead;
32
+ declare const step_pageVisit: typeof pageVisit;
33
+ declare const step_purchase: typeof purchase;
34
+ declare const step_search: typeof search;
35
+ declare const step_signUp: typeof signUp;
36
+ declare namespace step {
37
+ export { step_addToCart as addToCart, step_lead as lead, step_pageVisit as pageVisit, step_purchase as purchase, step_search as search, step_signUp as signUp };
38
+ }
39
+
40
+ export { env, step };