@walkeros/server-destination-pinterest 4.7.0-next-1790245733116 → 4.7.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/CHANGELOG.md +28 -14
- package/dist/dev.d.mts +2 -0
- package/dist/dev.d.ts +2 -0
- 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/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- 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 +178 -3
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
# @walkeros/server-destination-pinterest
|
|
2
2
|
|
|
3
|
-
## 4.7.0
|
|
3
|
+
## 4.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 74821ed: New `ip` and `userAgent` settings on the Meta, Pinterest, Snapchat,
|
|
8
|
+
TikTok, Reddit, X (Twitter), Bing, Criteo and Google Data Manager server
|
|
9
|
+
destinations. Requests now send the client IP and user agent in each vendor's
|
|
10
|
+
field by default, read from `ingest.ip`/`ingest.userAgent` or
|
|
11
|
+
`user.ip`/`user.userAgent`. A mapped value still wins; set either setting to
|
|
12
|
+
`false` to opt out.
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
|
6
15
|
|
|
7
|
-
- Updated dependencies [
|
|
16
|
+
- Updated dependencies [74821ed]
|
|
8
17
|
- Updated dependencies [06b498a]
|
|
9
|
-
- Updated dependencies [
|
|
10
|
-
- Updated dependencies [
|
|
18
|
+
- Updated dependencies [74821ed]
|
|
19
|
+
- Updated dependencies [64b06de]
|
|
20
|
+
- Updated dependencies [4b4937f]
|
|
21
|
+
- Updated dependencies [74821ed]
|
|
22
|
+
- Updated dependencies [74821ed]
|
|
23
|
+
- Updated dependencies [74821ed]
|
|
11
24
|
- Updated dependencies [06b498a]
|
|
12
|
-
- Updated dependencies [
|
|
13
|
-
- Updated dependencies [
|
|
14
|
-
- Updated dependencies [
|
|
15
|
-
- Updated dependencies [
|
|
16
|
-
- Updated dependencies [
|
|
17
|
-
- Updated dependencies [
|
|
18
|
-
- Updated dependencies [
|
|
19
|
-
- Updated dependencies [
|
|
20
|
-
|
|
21
|
-
- @walkeros/
|
|
25
|
+
- Updated dependencies [74821ed]
|
|
26
|
+
- Updated dependencies [74821ed]
|
|
27
|
+
- Updated dependencies [74821ed]
|
|
28
|
+
- Updated dependencies [74821ed]
|
|
29
|
+
- Updated dependencies [74821ed]
|
|
30
|
+
- Updated dependencies [e860006]
|
|
31
|
+
- Updated dependencies [74821ed]
|
|
32
|
+
- Updated dependencies [74821ed]
|
|
33
|
+
- Updated dependencies [4f89234]
|
|
34
|
+
- @walkeros/core@4.7.0
|
|
35
|
+
- @walkeros/server-core@4.7.0
|
|
22
36
|
|
|
23
37
|
## 4.6.1
|
|
24
38
|
|
package/dist/dev.d.mts
CHANGED
|
@@ -57,6 +57,8 @@ declare const SettingsSchema: z.ZodObject<{
|
|
|
57
57
|
url: z.ZodOptional<z.ZodString>;
|
|
58
58
|
user_data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
59
59
|
partner_name: z.ZodOptional<z.ZodString>;
|
|
60
|
+
ip: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodLiteral<false>]>>;
|
|
61
|
+
userAgent: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodLiteral<false>]>>;
|
|
60
62
|
}, z.core.$strip>;
|
|
61
63
|
type Settings = z.infer<typeof SettingsSchema>;
|
|
62
64
|
|
package/dist/dev.d.ts
CHANGED
|
@@ -57,6 +57,8 @@ declare const SettingsSchema: z.ZodObject<{
|
|
|
57
57
|
url: z.ZodOptional<z.ZodString>;
|
|
58
58
|
user_data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
59
59
|
partner_name: z.ZodOptional<z.ZodString>;
|
|
60
|
+
ip: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodLiteral<false>]>>;
|
|
61
|
+
userAgent: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodLiteral<false>]>>;
|
|
60
62
|
}, z.core.$strip>;
|
|
61
63
|
type Settings = z.infer<typeof SettingsSchema>;
|
|
62
64
|
|
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,s=(e,a)=>{for(var i in a)t(e,i,{get:a[i],enumerable:!0})},n={};s(n,{examples:()=>f,schemas:()=>o}),module.exports=(e=n,((e,s,n,o)=>{if(s&&"object"==typeof s||"function"==typeof s)for(let c of i(s))r.call(e,c)||c===n||t(e,c,{get:()=>s[c],enumerable:!(o=a(s,c))||o.enumerable});return e})(t({},"__esModule",{value:!0}),e));var o={};s(o,{ActionSourceSchema:()=>p,EventNameSchema:()=>m,MappingSchema:()=>v,SettingsSchema:()=>_,mapping:()=>g,settings:()=>h});var c=require("@walkeros/core/dev"),d=require("@walkeros/core/dev"),u=require("@walkeros/core/dev"),p=u.z.enum(["app_android","app_ios","web","offline"]),m=u.z.union([u.z.enum(["add_payment_info","add_to_cart","add_to_wishlist","app_install","app_open","checkout","contact","custom","customize_product","find_location","initiate_checkout","lead","page_visit","schedule","search","signup","start_trial","submit_application","subscribe","view_category","view_content","watch_video"]),u.z.string()]),l=d.z.union([d.schemas.MappingSchemas.ValueSchema,d.z.literal(!1)]),_=d.z.object({accessToken:d.z.string().min(1).describe("Pinterest conversion access token for Bearer authentication (like pina_ABC123...)"),adAccountId:d.z.string().regex(/^[0-9]+$/,"Ad account ID must contain only digits").describe("Pinterest ad account ID from Ads Manager (like 123456789)"),action_source:p.describe("Source of the event (web, app_android, app_ios, offline) (like web)").optional(),doNotHash:d.z.array(d.z.string()).describe("Array of user_data fields that should not be hashed (like ['external_id'])").optional(),test:d.z.boolean().describe("Enable test mode by appending ?test=true to the API URL (like true)").optional(),url:d.z.string().url().describe("Custom URL for Pinterest Conversions API endpoint (like https://api.pinterest.com/v5/)").optional(),user_data:d.z.record(d.z.string(),d.z.string()).describe("Mapping configuration for user data fields (like { em: 'user.email', ph: 'user.phone' })").optional(),partner_name:d.z.string().describe("Third-party partner name for attribution (like ss-walkeros)").optional(),ip:l.describe('Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }. Default: ["ingest.ip", "event.user.ip"]. false switches it off. A mapped user_data.client_ip_address wins.').optional(),userAgent:l.describe('Client user agent, sent as user_data.client_user_agent. Resolves against { ingest, event }. Default: ["ingest.userAgent", "event.user.userAgent"]. false switches it off. A mapped user_data.client_user_agent wins.').optional()}),v=require("@walkeros/core/dev").z.object({}),h=(0,c.zodToSchema)(_),g=(0,c.zodToSchema)(v),f={};s(f,{env:()=>b,step:()=>k});var b={};s(b,{push:()=>w,simulation:()=>y});var w={sendServer:async function(e,t,a){return{ok:!0,data:{num_events_received:1,num_events_processed:1,events:[{status:"processed"}]}}}},y=["sendServer"],k={};s(k,{addToCart:()=>O,checkout:()=>x,pageVisit:()=>P,search:()=>q,signup:()=>E});var S=require("@walkeros/core"),A="https://api.pinterest.com/v5/ad_accounts/123456789/events",z={headers:{Authorization:"Bearer s3cr3t"}},x={title:"Checkout",description:"A completed order is sent to the Pinterest Conversions API as a checkout event with value, currency, and contents.",in:(0,S.getEvent)("order complete",{id:"a1b2c3d4e5f60001",timestamp:1700000900,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Everyday Ruck Snack",price:"129.99",quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"browser",platform:"web",url:"https://shop.example.com"}}),mapping:{name:"checkout",data:{map:{custom_data:{map:{value:"data.total",currency:{key:"data.currency",value:"EUR"},order_id:"data.id",num_items:{fn:e=>e.nested.filter(e=>"product"===e.entity).length},contents:{loop:["nested",{condition:e=>(0,S.isObject)(e)&&"product"===e.entity,map:{id:"data.id",item_name:"data.name",item_price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}}}},out:[["sendServer",A,JSON.stringify({data:[{event_name:"checkout",event_id:"a1b2c3d4e5f60001",event_time:1700001,action_source:"web",user_data:{},custom_data:{value:249.99,currency:"EUR",order_id:"ORD-300",num_items:1,contents:[{id:"SKU-A1",item_name:"Everyday Ruck Snack",item_price:"129.99",quantity:2}]},event_source_url:"https://shop.example.com"}]}),z]]},O={title:"Add to cart",description:"A product add is sent to Pinterest as an add_to_cart conversion with the added item details.",in:(0,S.getEvent)("product add",{id:"a1b2c3d4e5f60002",timestamp:1700000901,data:{id:"SKU-B2",name:"Cool Cap",price:"42.00",quantity:1},user:{id:"user-456"},source:{type:"browser",platform:"web",url:"https://shop.example.com/products"}}),mapping:{name:"add_to_cart",data:{map:{custom_data:{map:{value:"data.price",currency:{value:"EUR"},contents:{set:[{map:{id:"data.id",item_name:"data.name",item_price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}}}},out:[["sendServer",A,JSON.stringify({data:[{event_name:"add_to_cart",event_id:"a1b2c3d4e5f60002",event_time:1700001,action_source:"web",user_data:{},custom_data:{value:"42.00",currency:"EUR",contents:[{id:"SKU-B2",item_name:"Cool Cap",item_price:"42.00",quantity:1}]},event_source_url:"https://shop.example.com/products"}]}),z]]},P={title:"Page visit",description:"A page view is sent to Pinterest as a page_visit conversion with the source URL.",in:(0,S.getEvent)("page view",{id:"a1b2c3d4e5f60003",timestamp:1700000902,user:{id:"user-789"},source:{type:"browser",platform:"web",url:"https://www.example.com/docs/"}}),mapping:{name:"page_visit"},out:[["sendServer",A,JSON.stringify({data:[{event_name:"page_visit",event_id:"a1b2c3d4e5f60003",event_time:1700001,action_source:"web",user_data:{},event_source_url:"https://www.example.com/docs/"}]}),z]]},q={title:"Search",description:"A site search event is forwarded to Pinterest as a search conversion with the query in custom data.",in:(0,S.getEvent)("entity action",{id:"a1b2c3d4e5f60004",timestamp:1700000903,name:"site search",data:{query:"walkerOS destinations"},user:{id:"user-101"},source:{type:"browser",platform:"web",url:"https://www.example.com/search"}}),mapping:{name:"search",data:{map:{custom_data:{map:{search_string:"data.query"}}}}},out:[["sendServer",A,JSON.stringify({data:[{event_name:"search",event_id:"a1b2c3d4e5f60004",event_time:1700001,action_source:"web",user_data:{},custom_data:{search_string:"walkerOS destinations"},event_source_url:"https://www.example.com/search"}]}),z]]},E={title:"Signup",description:"A user signup is sent to Pinterest as a signup conversion with the hashed email and external id.",in:(0,S.getEvent)("entity action",{id:"a1b2c3d4e5f60005",timestamp:1700000904,name:"user signup",data:{method:"email"},user:{id:"new-user-1",email:"new@example.com"},source:{type:"browser",platform:"web",url:"https://www.example.com/register"}}),mapping:{name:"signup",data:{map:{user_data:{map:{em:{set:["user.email"]},external_id:{set:["user.id"]}}}}}},out:[["sendServer",A,JSON.stringify({data:[{event_name:"signup",event_id:"a1b2c3d4e5f60005",event_time:1700001,action_source:"web",user_data:{em:["f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716"],external_id:["b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde"]},event_source_url:"https://www.example.com/register"}]}),z]]};//# 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/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 'Pinterest conversion access token for Bearer authentication (like pina_ABC123...)',\n ),\n adAccountId: z\n .string()\n .regex(/^[0-9]+$/, 'Ad account ID must contain only digits')\n .describe('Pinterest ad account ID from Ads Manager (like 123456789)'),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (web, app_android, app_ios, offline) (like web)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\n \"Array of user_data fields that should not be hashed (like ['external_id'])\",\n )\n .optional(),\n test: z\n .boolean()\n .describe(\n 'Enable test mode by appending ?test=true to the API URL (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Pinterest Conversions API endpoint (like https://api.pinterest.com/v5/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user data fields (like { em: 'user.email', ph: 'user.phone' })\",\n )\n .optional(),\n partner_name: z\n .string()\n .describe('Third-party partner name for attribution (like ss-walkeros)')\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://developers.pinterest.com/docs/conversions/conversions/\n */\nexport const ActionSourceSchema = z.enum([\n 'app_android',\n 'app_ios',\n 'web',\n 'offline',\n]);\n\n/**\n * Event Name\n * Standard Pinterest CAPI event names or custom event identifiers\n */\nexport const EventNameSchema = z.union([\n z.enum([\n 'add_payment_info',\n 'add_to_cart',\n 'add_to_wishlist',\n 'app_install',\n 'app_open',\n 'checkout',\n 'contact',\n 'custom',\n 'customize_product',\n 'find_location',\n 'initiate_checkout',\n 'lead',\n 'page_visit',\n 'schedule',\n 'search',\n 'signup',\n 'start_trial',\n 'submit_application',\n 'subscribe',\n 'view_category',\n 'view_content',\n 'watch_video',\n ]),\n z.string(), // Allow custom event names\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Pinterest Conversions API Mapping Schema\n * Pinterest 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 Pinterest Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nasync function mockSendServer(\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n): Promise<SendResponse> {\n // Simulate successful Pinterest API response\n return {\n ok: true,\n data: {\n num_events_received: 1,\n num_events_processed: 1,\n events: [{ status: 'processed' }],\n },\n };\n}\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Pinterest Conversions API events without making\n * actual HTTP requests to Pinterest'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 * Pinterest Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), { headers })` where\n * `endpoint = ${settings.url}ad_accounts/${settings.adAccountId}/events`\n * and `body = { data: [hashedServerEvent] }`.\n *\n * Test fixture pins `accessToken = 's3cr3t'` and `adAccountId = '123456789'`,\n * so every endpoint resolves to:\n * https://api.pinterest.com/v5/ad_accounts/123456789/events\n *\n * Body is emitted with keys in insertion order from push.ts:\n * 1. event_name\n * 2. event_id\n * 3. event_time (unix seconds; `Math.round(event.timestamp / 1000)`)\n * 4. action_source (default 'web')\n * 5. ...restEventData (from mapping.data, excluding user_data/custom_data)\n * 6. user_data (hashed per Pinterest's PII requirements)\n * 7. custom_data (only when mapping sets custom_data)\n * 8. event_source_url (appended when action_source === 'web')\n *\n * The `options` argument carries the Authorization header.\n */\nconst ENDPOINT = 'https://api.pinterest.com/v5/ad_accounts/123456789/events';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const checkout: Flow.StepExample = {\n title: 'Checkout',\n description:\n 'A completed order is sent to the Pinterest Conversions API as a checkout event with value, currency, and contents.',\n in: getEvent('order complete', {\n id: 'a1b2c3d4e5f60001',\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 price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com',\n },\n }),\n mapping: {\n name: 'checkout',\n data: {\n map: {\n custom_data: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n order_id: 'data.id',\n num_items: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n contents: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n item_name: 'data.name',\n item_price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'checkout',\n event_id: 'a1b2c3d4e5f60001',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n value: 249.99,\n currency: 'EUR',\n order_id: 'ORD-300',\n num_items: 1,\n contents: [\n {\n id: 'SKU-A1',\n item_name: 'Everyday Ruck Snack',\n item_price: '129.99',\n quantity: 2,\n },\n ],\n },\n event_source_url: 'https://shop.example.com',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Pinterest as an add_to_cart conversion with the added item details.',\n in: getEvent('product add', {\n id: 'a1b2c3d4e5f60002',\n timestamp: 1700000901,\n data: { id: 'SKU-B2', name: 'Cool Cap', price: '42.00', quantity: 1 },\n user: { id: 'user-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/products',\n },\n }),\n mapping: {\n name: 'add_to_cart',\n data: {\n map: {\n custom_data: {\n map: {\n value: 'data.price',\n currency: { value: 'EUR' },\n contents: {\n set: [\n {\n map: {\n id: 'data.id',\n item_name: 'data.name',\n item_price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'add_to_cart',\n event_id: 'a1b2c3d4e5f60002',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n value: '42.00',\n currency: 'EUR',\n contents: [\n {\n id: 'SKU-B2',\n item_name: 'Cool Cap',\n item_price: '42.00',\n quantity: 1,\n },\n ],\n },\n event_source_url: 'https://shop.example.com/products',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n title: 'Page visit',\n description:\n 'A page view is sent to Pinterest as a page_visit conversion with the source URL.',\n in: getEvent('page view', {\n id: 'a1b2c3d4e5f60003',\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/docs/',\n },\n }),\n mapping: {\n name: 'page_visit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'page_visit',\n event_id: 'a1b2c3d4e5f60003',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n event_source_url: 'https://www.example.com/docs/',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A site search event is forwarded to Pinterest as a search conversion with the query in custom data.',\n in: getEvent('entity action', {\n id: 'a1b2c3d4e5f60004',\n timestamp: 1700000903,\n name: 'site search',\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/search',\n },\n }),\n mapping: {\n name: 'search',\n data: {\n map: {\n custom_data: {\n map: {\n search_string: 'data.query',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'search',\n event_id: 'a1b2c3d4e5f60004',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n search_string: 'walkerOS destinations',\n },\n event_source_url: 'https://www.example.com/search',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signup: Flow.StepExample = {\n title: 'Signup',\n description:\n 'A user signup is sent to Pinterest as a signup conversion with the hashed email and external id.',\n in: getEvent('entity action', {\n id: 'a1b2c3d4e5f60005',\n timestamp: 1700000904,\n name: 'user signup',\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/register',\n },\n }),\n mapping: {\n name: 'signup',\n data: {\n map: {\n user_data: {\n map: {\n em: { set: ['user.email'] },\n external_id: { set: ['user.id'] },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'signup',\n event_id: 'a1b2c3d4e5f60005',\n event_time: 1700001,\n action_source: 'web',\n user_data: {\n // sha256('new@example.com')\n em: [\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n ],\n // sha256('new-user-1')\n external_id: [\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n ],\n },\n event_source_url: 'https://www.example.com/register',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["import_dev","import_dev","import_dev"]}
|
|
1
|
+
{"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/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 { schemas, z } from '@walkeros/core/dev';\nimport { ActionSourceSchema } from './primitives';\n\nconst InputSchema = z.union([\n schemas.MappingSchemas.ValueSchema,\n z.literal(false),\n]);\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Pinterest conversion access token for Bearer authentication (like pina_ABC123...)',\n ),\n adAccountId: z\n .string()\n .regex(/^[0-9]+$/, 'Ad account ID must contain only digits')\n .describe('Pinterest ad account ID from Ads Manager (like 123456789)'),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (web, app_android, app_ios, offline) (like web)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\n \"Array of user_data fields that should not be hashed (like ['external_id'])\",\n )\n .optional(),\n test: z\n .boolean()\n .describe(\n 'Enable test mode by appending ?test=true to the API URL (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Pinterest Conversions API endpoint (like https://api.pinterest.com/v5/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user data fields (like { em: 'user.email', ph: 'user.phone' })\",\n )\n .optional(),\n partner_name: z\n .string()\n .describe('Third-party partner name for attribution (like ss-walkeros)')\n .optional(),\n ip: InputSchema.describe(\n 'Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }. Default: [\"ingest.ip\", \"event.user.ip\"]. false switches it off. A mapped user_data.client_ip_address wins.',\n ).optional(),\n userAgent: InputSchema.describe(\n 'Client user agent, sent as user_data.client_user_agent. Resolves against { ingest, event }. Default: [\"ingest.userAgent\", \"event.user.userAgent\"]. false switches it off. A mapped user_data.client_user_agent wins.',\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://developers.pinterest.com/docs/conversions/conversions/\n */\nexport const ActionSourceSchema = z.enum([\n 'app_android',\n 'app_ios',\n 'web',\n 'offline',\n]);\n\n/**\n * Event Name\n * Standard Pinterest CAPI event names or custom event identifiers\n */\nexport const EventNameSchema = z.union([\n z.enum([\n 'add_payment_info',\n 'add_to_cart',\n 'add_to_wishlist',\n 'app_install',\n 'app_open',\n 'checkout',\n 'contact',\n 'custom',\n 'customize_product',\n 'find_location',\n 'initiate_checkout',\n 'lead',\n 'page_visit',\n 'schedule',\n 'search',\n 'signup',\n 'start_trial',\n 'submit_application',\n 'subscribe',\n 'view_category',\n 'view_content',\n 'watch_video',\n ]),\n z.string(), // Allow custom event names\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Pinterest Conversions API Mapping Schema\n * Pinterest 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 Pinterest Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nasync function mockSendServer(\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n): Promise<SendResponse> {\n // Simulate successful Pinterest API response\n return {\n ok: true,\n data: {\n num_events_received: 1,\n num_events_processed: 1,\n events: [{ status: 'processed' }],\n },\n };\n}\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Pinterest Conversions API events without making\n * actual HTTP requests to Pinterest'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 * Pinterest Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), { headers })` where\n * `endpoint = ${settings.url}ad_accounts/${settings.adAccountId}/events`\n * and `body = { data: [hashedServerEvent] }`.\n *\n * Test fixture pins `accessToken = 's3cr3t'` and `adAccountId = '123456789'`,\n * so every endpoint resolves to:\n * https://api.pinterest.com/v5/ad_accounts/123456789/events\n *\n * Body is emitted with keys in insertion order from push.ts:\n * 1. event_name\n * 2. event_id\n * 3. event_time (unix seconds; `Math.round(event.timestamp / 1000)`)\n * 4. action_source (default 'web')\n * 5. ...restEventData (from mapping.data, excluding user_data/custom_data)\n * 6. user_data (hashed per Pinterest's PII requirements)\n * 7. custom_data (only when mapping sets custom_data)\n * 8. event_source_url (appended when action_source === 'web')\n *\n * The `options` argument carries the Authorization header.\n */\nconst ENDPOINT = 'https://api.pinterest.com/v5/ad_accounts/123456789/events';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const checkout: Flow.StepExample = {\n title: 'Checkout',\n description:\n 'A completed order is sent to the Pinterest Conversions API as a checkout event with value, currency, and contents.',\n in: getEvent('order complete', {\n id: 'a1b2c3d4e5f60001',\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 price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com',\n },\n }),\n mapping: {\n name: 'checkout',\n data: {\n map: {\n custom_data: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n order_id: 'data.id',\n num_items: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n contents: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n item_name: 'data.name',\n item_price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'checkout',\n event_id: 'a1b2c3d4e5f60001',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n value: 249.99,\n currency: 'EUR',\n order_id: 'ORD-300',\n num_items: 1,\n contents: [\n {\n id: 'SKU-A1',\n item_name: 'Everyday Ruck Snack',\n item_price: '129.99',\n quantity: 2,\n },\n ],\n },\n event_source_url: 'https://shop.example.com',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Pinterest as an add_to_cart conversion with the added item details.',\n in: getEvent('product add', {\n id: 'a1b2c3d4e5f60002',\n timestamp: 1700000901,\n data: { id: 'SKU-B2', name: 'Cool Cap', price: '42.00', quantity: 1 },\n user: { id: 'user-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/products',\n },\n }),\n mapping: {\n name: 'add_to_cart',\n data: {\n map: {\n custom_data: {\n map: {\n value: 'data.price',\n currency: { value: 'EUR' },\n contents: {\n set: [\n {\n map: {\n id: 'data.id',\n item_name: 'data.name',\n item_price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'add_to_cart',\n event_id: 'a1b2c3d4e5f60002',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n value: '42.00',\n currency: 'EUR',\n contents: [\n {\n id: 'SKU-B2',\n item_name: 'Cool Cap',\n item_price: '42.00',\n quantity: 1,\n },\n ],\n },\n event_source_url: 'https://shop.example.com/products',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n title: 'Page visit',\n description:\n 'A page view is sent to Pinterest as a page_visit conversion with the source URL.',\n in: getEvent('page view', {\n id: 'a1b2c3d4e5f60003',\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/docs/',\n },\n }),\n mapping: {\n name: 'page_visit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'page_visit',\n event_id: 'a1b2c3d4e5f60003',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n event_source_url: 'https://www.example.com/docs/',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A site search event is forwarded to Pinterest as a search conversion with the query in custom data.',\n in: getEvent('entity action', {\n id: 'a1b2c3d4e5f60004',\n timestamp: 1700000903,\n name: 'site search',\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/search',\n },\n }),\n mapping: {\n name: 'search',\n data: {\n map: {\n custom_data: {\n map: {\n search_string: 'data.query',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'search',\n event_id: 'a1b2c3d4e5f60004',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n search_string: 'walkerOS destinations',\n },\n event_source_url: 'https://www.example.com/search',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signup: Flow.StepExample = {\n title: 'Signup',\n description:\n 'A user signup is sent to Pinterest as a signup conversion with the hashed email and external id.',\n in: getEvent('entity action', {\n id: 'a1b2c3d4e5f60005',\n timestamp: 1700000904,\n name: 'user signup',\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/register',\n },\n }),\n mapping: {\n name: 'signup',\n data: {\n map: {\n user_data: {\n map: {\n em: { set: ['user.email'] },\n external_id: { set: ['user.id'] },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'signup',\n event_id: 'a1b2c3d4e5f60005',\n event_time: 1700001,\n action_source: 'web',\n user_data: {\n // sha256('new@example.com')\n em: [\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n ],\n // sha256('new-user-1')\n external_id: [\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n ],\n },\n event_source_url: 'https://www.example.com/register',\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
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=(t,a)=>{for(var i in a)e(t,i,{get:a[i],enumerable:!0})},a={};t(a,{ActionSourceSchema:()=>
|
|
1
|
+
var e=Object.defineProperty,t=(t,a)=>{for(var i in a)e(t,i,{get:a[i],enumerable:!0})},a={};t(a,{ActionSourceSchema:()=>o,EventNameSchema:()=>c,MappingSchema:()=>m,SettingsSchema:()=>p,mapping:()=>_,settings:()=>l});import{zodToSchema as i}from"@walkeros/core/dev";import{schemas as s,z as r}from"@walkeros/core/dev";import{z as n}from"@walkeros/core/dev";var o=n.enum(["app_android","app_ios","web","offline"]),c=n.union([n.enum(["add_payment_info","add_to_cart","add_to_wishlist","app_install","app_open","checkout","contact","custom","customize_product","find_location","initiate_checkout","lead","page_visit","schedule","search","signup","start_trial","submit_application","subscribe","view_category","view_content","watch_video"]),n.string()]),d=r.union([s.MappingSchemas.ValueSchema,r.literal(!1)]),p=r.object({accessToken:r.string().min(1).describe("Pinterest conversion access token for Bearer authentication (like pina_ABC123...)"),adAccountId:r.string().regex(/^[0-9]+$/,"Ad account ID must contain only digits").describe("Pinterest ad account ID from Ads Manager (like 123456789)"),action_source:o.describe("Source of the event (web, app_android, app_ios, offline) (like web)").optional(),doNotHash:r.array(r.string()).describe("Array of user_data fields that should not be hashed (like ['external_id'])").optional(),test:r.boolean().describe("Enable test mode by appending ?test=true to the API URL (like true)").optional(),url:r.string().url().describe("Custom URL for Pinterest Conversions API endpoint (like https://api.pinterest.com/v5/)").optional(),user_data:r.record(r.string(),r.string()).describe("Mapping configuration for user data fields (like { em: 'user.email', ph: 'user.phone' })").optional(),partner_name:r.string().describe("Third-party partner name for attribution (like ss-walkeros)").optional(),ip:d.describe('Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }. Default: ["ingest.ip", "event.user.ip"]. false switches it off. A mapped user_data.client_ip_address wins.').optional(),userAgent:d.describe('Client user agent, sent as user_data.client_user_agent. Resolves against { ingest, event }. Default: ["ingest.userAgent", "event.user.userAgent"]. false switches it off. A mapped user_data.client_user_agent wins.').optional()});import{z as u}from"@walkeros/core/dev";var m=u.object({}),l=i(p),_=i(m),v={};t(v,{env:()=>h,step:()=>w});var h={};t(h,{push:()=>f,simulation:()=>g});var f={sendServer:async function(e,t,a){return{ok:!0,data:{num_events_received:1,num_events_processed:1,events:[{status:"processed"}]}}}},g=["sendServer"],w={};t(w,{addToCart:()=>x,checkout:()=>A,pageVisit:()=>P,search:()=>R,signup:()=>C});import{getEvent as b,isObject as y}from"@walkeros/core";var k="https://api.pinterest.com/v5/ad_accounts/123456789/events",S={headers:{Authorization:"Bearer s3cr3t"}},A={title:"Checkout",description:"A completed order is sent to the Pinterest Conversions API as a checkout event with value, currency, and contents.",in:b("order complete",{id:"a1b2c3d4e5f60001",timestamp:1700000900,data:{id:"ORD-300",total:249.99,currency:"EUR"},nested:[{entity:"product",data:{id:"SKU-A1",name:"Everyday Ruck Snack",price:"129.99",quantity:2}}],user:{id:"user-123",device:"device-456"},source:{type:"browser",platform:"web",url:"https://shop.example.com"}}),mapping:{name:"checkout",data:{map:{custom_data:{map:{value:"data.total",currency:{key:"data.currency",value:"EUR"},order_id:"data.id",num_items:{fn:e=>e.nested.filter(e=>"product"===e.entity).length},contents:{loop:["nested",{condition:e=>y(e)&&"product"===e.entity,map:{id:"data.id",item_name:"data.name",item_price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}}}},out:[["sendServer",k,JSON.stringify({data:[{event_name:"checkout",event_id:"a1b2c3d4e5f60001",event_time:1700001,action_source:"web",user_data:{},custom_data:{value:249.99,currency:"EUR",order_id:"ORD-300",num_items:1,contents:[{id:"SKU-A1",item_name:"Everyday Ruck Snack",item_price:"129.99",quantity:2}]},event_source_url:"https://shop.example.com"}]}),S]]},x={title:"Add to cart",description:"A product add is sent to Pinterest as an add_to_cart conversion with the added item details.",in:b("product add",{id:"a1b2c3d4e5f60002",timestamp:1700000901,data:{id:"SKU-B2",name:"Cool Cap",price:"42.00",quantity:1},user:{id:"user-456"},source:{type:"browser",platform:"web",url:"https://shop.example.com/products"}}),mapping:{name:"add_to_cart",data:{map:{custom_data:{map:{value:"data.price",currency:{value:"EUR"},contents:{set:[{map:{id:"data.id",item_name:"data.name",item_price:"data.price",quantity:{key:"data.quantity",value:1}}}]}}}}}},out:[["sendServer",k,JSON.stringify({data:[{event_name:"add_to_cart",event_id:"a1b2c3d4e5f60002",event_time:1700001,action_source:"web",user_data:{},custom_data:{value:"42.00",currency:"EUR",contents:[{id:"SKU-B2",item_name:"Cool Cap",item_price:"42.00",quantity:1}]},event_source_url:"https://shop.example.com/products"}]}),S]]},P={title:"Page visit",description:"A page view is sent to Pinterest as a page_visit conversion with the source URL.",in:b("page view",{id:"a1b2c3d4e5f60003",timestamp:1700000902,user:{id:"user-789"},source:{type:"browser",platform:"web",url:"https://www.example.com/docs/"}}),mapping:{name:"page_visit"},out:[["sendServer",k,JSON.stringify({data:[{event_name:"page_visit",event_id:"a1b2c3d4e5f60003",event_time:1700001,action_source:"web",user_data:{},event_source_url:"https://www.example.com/docs/"}]}),S]]},R={title:"Search",description:"A site search event is forwarded to Pinterest as a search conversion with the query in custom data.",in:b("entity action",{id:"a1b2c3d4e5f60004",timestamp:1700000903,name:"site search",data:{query:"walkerOS destinations"},user:{id:"user-101"},source:{type:"browser",platform:"web",url:"https://www.example.com/search"}}),mapping:{name:"search",data:{map:{custom_data:{map:{search_string:"data.query"}}}}},out:[["sendServer",k,JSON.stringify({data:[{event_name:"search",event_id:"a1b2c3d4e5f60004",event_time:1700001,action_source:"web",user_data:{},custom_data:{search_string:"walkerOS destinations"},event_source_url:"https://www.example.com/search"}]}),S]]},C={title:"Signup",description:"A user signup is sent to Pinterest as a signup conversion with the hashed email and external id.",in:b("entity action",{id:"a1b2c3d4e5f60005",timestamp:1700000904,name:"user signup",data:{method:"email"},user:{id:"new-user-1",email:"new@example.com"},source:{type:"browser",platform:"web",url:"https://www.example.com/register"}}),mapping:{name:"signup",data:{map:{user_data:{map:{em:{set:["user.email"]},external_id:{set:["user.id"]}}}}}},out:[["sendServer",k,JSON.stringify({data:[{event_name:"signup",event_id:"a1b2c3d4e5f60005",event_time:1700001,action_source:"web",user_data:{em:["f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716"],external_id:["b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde"]},event_source_url:"https://www.example.com/register"}]}),S]]};export{v as examples,a as schemas};//# sourceMappingURL=dev.mjs.map
|
package/dist/dev.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/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 'Pinterest conversion access token for Bearer authentication (like pina_ABC123...)',\n ),\n adAccountId: z\n .string()\n .regex(/^[0-9]+$/, 'Ad account ID must contain only digits')\n .describe('Pinterest ad account ID from Ads Manager (like 123456789)'),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (web, app_android, app_ios, offline) (like web)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\n \"Array of user_data fields that should not be hashed (like ['external_id'])\",\n )\n .optional(),\n test: z\n .boolean()\n .describe(\n 'Enable test mode by appending ?test=true to the API URL (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Pinterest Conversions API endpoint (like https://api.pinterest.com/v5/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user data fields (like { em: 'user.email', ph: 'user.phone' })\",\n )\n .optional(),\n partner_name: z\n .string()\n .describe('Third-party partner name for attribution (like ss-walkeros)')\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://developers.pinterest.com/docs/conversions/conversions/\n */\nexport const ActionSourceSchema = z.enum([\n 'app_android',\n 'app_ios',\n 'web',\n 'offline',\n]);\n\n/**\n * Event Name\n * Standard Pinterest CAPI event names or custom event identifiers\n */\nexport const EventNameSchema = z.union([\n z.enum([\n 'add_payment_info',\n 'add_to_cart',\n 'add_to_wishlist',\n 'app_install',\n 'app_open',\n 'checkout',\n 'contact',\n 'custom',\n 'customize_product',\n 'find_location',\n 'initiate_checkout',\n 'lead',\n 'page_visit',\n 'schedule',\n 'search',\n 'signup',\n 'start_trial',\n 'submit_application',\n 'subscribe',\n 'view_category',\n 'view_content',\n 'watch_video',\n ]),\n z.string(), // Allow custom event names\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Pinterest Conversions API Mapping Schema\n * Pinterest 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 Pinterest Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nasync function mockSendServer(\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n): Promise<SendResponse> {\n // Simulate successful Pinterest API response\n return {\n ok: true,\n data: {\n num_events_received: 1,\n num_events_processed: 1,\n events: [{ status: 'processed' }],\n },\n };\n}\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Pinterest Conversions API events without making\n * actual HTTP requests to Pinterest'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 * Pinterest Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), { headers })` where\n * `endpoint = ${settings.url}ad_accounts/${settings.adAccountId}/events`\n * and `body = { data: [hashedServerEvent] }`.\n *\n * Test fixture pins `accessToken = 's3cr3t'` and `adAccountId = '123456789'`,\n * so every endpoint resolves to:\n * https://api.pinterest.com/v5/ad_accounts/123456789/events\n *\n * Body is emitted with keys in insertion order from push.ts:\n * 1. event_name\n * 2. event_id\n * 3. event_time (unix seconds; `Math.round(event.timestamp / 1000)`)\n * 4. action_source (default 'web')\n * 5. ...restEventData (from mapping.data, excluding user_data/custom_data)\n * 6. user_data (hashed per Pinterest's PII requirements)\n * 7. custom_data (only when mapping sets custom_data)\n * 8. event_source_url (appended when action_source === 'web')\n *\n * The `options` argument carries the Authorization header.\n */\nconst ENDPOINT = 'https://api.pinterest.com/v5/ad_accounts/123456789/events';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const checkout: Flow.StepExample = {\n title: 'Checkout',\n description:\n 'A completed order is sent to the Pinterest Conversions API as a checkout event with value, currency, and contents.',\n in: getEvent('order complete', {\n id: 'a1b2c3d4e5f60001',\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 price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com',\n },\n }),\n mapping: {\n name: 'checkout',\n data: {\n map: {\n custom_data: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n order_id: 'data.id',\n num_items: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n contents: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n item_name: 'data.name',\n item_price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'checkout',\n event_id: 'a1b2c3d4e5f60001',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n value: 249.99,\n currency: 'EUR',\n order_id: 'ORD-300',\n num_items: 1,\n contents: [\n {\n id: 'SKU-A1',\n item_name: 'Everyday Ruck Snack',\n item_price: '129.99',\n quantity: 2,\n },\n ],\n },\n event_source_url: 'https://shop.example.com',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Pinterest as an add_to_cart conversion with the added item details.',\n in: getEvent('product add', {\n id: 'a1b2c3d4e5f60002',\n timestamp: 1700000901,\n data: { id: 'SKU-B2', name: 'Cool Cap', price: '42.00', quantity: 1 },\n user: { id: 'user-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/products',\n },\n }),\n mapping: {\n name: 'add_to_cart',\n data: {\n map: {\n custom_data: {\n map: {\n value: 'data.price',\n currency: { value: 'EUR' },\n contents: {\n set: [\n {\n map: {\n id: 'data.id',\n item_name: 'data.name',\n item_price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'add_to_cart',\n event_id: 'a1b2c3d4e5f60002',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n value: '42.00',\n currency: 'EUR',\n contents: [\n {\n id: 'SKU-B2',\n item_name: 'Cool Cap',\n item_price: '42.00',\n quantity: 1,\n },\n ],\n },\n event_source_url: 'https://shop.example.com/products',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n title: 'Page visit',\n description:\n 'A page view is sent to Pinterest as a page_visit conversion with the source URL.',\n in: getEvent('page view', {\n id: 'a1b2c3d4e5f60003',\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/docs/',\n },\n }),\n mapping: {\n name: 'page_visit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'page_visit',\n event_id: 'a1b2c3d4e5f60003',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n event_source_url: 'https://www.example.com/docs/',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A site search event is forwarded to Pinterest as a search conversion with the query in custom data.',\n in: getEvent('entity action', {\n id: 'a1b2c3d4e5f60004',\n timestamp: 1700000903,\n name: 'site search',\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/search',\n },\n }),\n mapping: {\n name: 'search',\n data: {\n map: {\n custom_data: {\n map: {\n search_string: 'data.query',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'search',\n event_id: 'a1b2c3d4e5f60004',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n search_string: 'walkerOS destinations',\n },\n event_source_url: 'https://www.example.com/search',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signup: Flow.StepExample = {\n title: 'Signup',\n description:\n 'A user signup is sent to Pinterest as a signup conversion with the hashed email and external id.',\n in: getEvent('entity action', {\n id: 'a1b2c3d4e5f60005',\n timestamp: 1700000904,\n name: 'user signup',\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/register',\n },\n }),\n mapping: {\n name: 'signup',\n data: {\n map: {\n user_data: {\n map: {\n em: { set: ['user.email'] },\n external_id: { set: ['user.id'] },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'signup',\n event_id: 'a1b2c3d4e5f60005',\n event_time: 1700001,\n action_source: 'web',\n user_data: {\n // sha256('new@example.com')\n em: [\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n ],\n // sha256('new-user-1')\n external_id: [\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n ],\n },\n event_source_url: 'https://www.example.com/register',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["z","z","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/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 { schemas, z } from '@walkeros/core/dev';\nimport { ActionSourceSchema } from './primitives';\n\nconst InputSchema = z.union([\n schemas.MappingSchemas.ValueSchema,\n z.literal(false),\n]);\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'Pinterest conversion access token for Bearer authentication (like pina_ABC123...)',\n ),\n adAccountId: z\n .string()\n .regex(/^[0-9]+$/, 'Ad account ID must contain only digits')\n .describe('Pinterest ad account ID from Ads Manager (like 123456789)'),\n action_source: ActionSourceSchema.describe(\n 'Source of the event (web, app_android, app_ios, offline) (like web)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\n \"Array of user_data fields that should not be hashed (like ['external_id'])\",\n )\n .optional(),\n test: z\n .boolean()\n .describe(\n 'Enable test mode by appending ?test=true to the API URL (like true)',\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for Pinterest Conversions API endpoint (like https://api.pinterest.com/v5/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user data fields (like { em: 'user.email', ph: 'user.phone' })\",\n )\n .optional(),\n partner_name: z\n .string()\n .describe('Third-party partner name for attribution (like ss-walkeros)')\n .optional(),\n ip: InputSchema.describe(\n 'Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }. Default: [\"ingest.ip\", \"event.user.ip\"]. false switches it off. A mapped user_data.client_ip_address wins.',\n ).optional(),\n userAgent: InputSchema.describe(\n 'Client user agent, sent as user_data.client_user_agent. Resolves against { ingest, event }. Default: [\"ingest.userAgent\", \"event.user.userAgent\"]. false switches it off. A mapped user_data.client_user_agent wins.',\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://developers.pinterest.com/docs/conversions/conversions/\n */\nexport const ActionSourceSchema = z.enum([\n 'app_android',\n 'app_ios',\n 'web',\n 'offline',\n]);\n\n/**\n * Event Name\n * Standard Pinterest CAPI event names or custom event identifiers\n */\nexport const EventNameSchema = z.union([\n z.enum([\n 'add_payment_info',\n 'add_to_cart',\n 'add_to_wishlist',\n 'app_install',\n 'app_open',\n 'checkout',\n 'contact',\n 'custom',\n 'customize_product',\n 'find_location',\n 'initiate_checkout',\n 'lead',\n 'page_visit',\n 'schedule',\n 'search',\n 'signup',\n 'start_trial',\n 'submit_application',\n 'subscribe',\n 'view_category',\n 'view_content',\n 'watch_video',\n ]),\n z.string(), // Allow custom event names\n]);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * Pinterest Conversions API Mapping Schema\n * Pinterest 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 Pinterest Conversions API destination\n *\n * These environments provide standardized mock structures for testing\n * and development without requiring actual HTTP requests.\n */\n\n/**\n * Mock sendServer function that simulates successful HTTP responses\n */\nasync function mockSendServer(\n url: string,\n data?: SendDataValue,\n options?: SendServerOptions,\n): Promise<SendResponse> {\n // Simulate successful Pinterest API response\n return {\n ok: true,\n data: {\n num_events_received: 1,\n num_events_processed: 1,\n events: [{ status: 'processed' }],\n },\n };\n}\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing Pinterest Conversions API events without making\n * actual HTTP requests to Pinterest'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 * Pinterest Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), { headers })` where\n * `endpoint = ${settings.url}ad_accounts/${settings.adAccountId}/events`\n * and `body = { data: [hashedServerEvent] }`.\n *\n * Test fixture pins `accessToken = 's3cr3t'` and `adAccountId = '123456789'`,\n * so every endpoint resolves to:\n * https://api.pinterest.com/v5/ad_accounts/123456789/events\n *\n * Body is emitted with keys in insertion order from push.ts:\n * 1. event_name\n * 2. event_id\n * 3. event_time (unix seconds; `Math.round(event.timestamp / 1000)`)\n * 4. action_source (default 'web')\n * 5. ...restEventData (from mapping.data, excluding user_data/custom_data)\n * 6. user_data (hashed per Pinterest's PII requirements)\n * 7. custom_data (only when mapping sets custom_data)\n * 8. event_source_url (appended when action_source === 'web')\n *\n * The `options` argument carries the Authorization header.\n */\nconst ENDPOINT = 'https://api.pinterest.com/v5/ad_accounts/123456789/events';\nconst OPTIONS = {\n headers: { Authorization: 'Bearer s3cr3t' },\n};\n\nexport const checkout: Flow.StepExample = {\n title: 'Checkout',\n description:\n 'A completed order is sent to the Pinterest Conversions API as a checkout event with value, currency, and contents.',\n in: getEvent('order complete', {\n id: 'a1b2c3d4e5f60001',\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 price: '129.99',\n quantity: 2,\n },\n },\n ],\n user: { id: 'user-123', device: 'device-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com',\n },\n }),\n mapping: {\n name: 'checkout',\n data: {\n map: {\n custom_data: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n order_id: 'data.id',\n num_items: {\n fn: (event: unknown) =>\n (event as WalkerOS.Event).nested.filter(\n (item) => item.entity === 'product',\n ).length,\n },\n contents: {\n loop: [\n 'nested',\n {\n condition: (entity: unknown) =>\n isObject(entity) && entity.entity === 'product',\n map: {\n id: 'data.id',\n item_name: 'data.name',\n item_price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'checkout',\n event_id: 'a1b2c3d4e5f60001',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n value: 249.99,\n currency: 'EUR',\n order_id: 'ORD-300',\n num_items: 1,\n contents: [\n {\n id: 'SKU-A1',\n item_name: 'Everyday Ruck Snack',\n item_price: '129.99',\n quantity: 2,\n },\n ],\n },\n event_source_url: 'https://shop.example.com',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A product add is sent to Pinterest as an add_to_cart conversion with the added item details.',\n in: getEvent('product add', {\n id: 'a1b2c3d4e5f60002',\n timestamp: 1700000901,\n data: { id: 'SKU-B2', name: 'Cool Cap', price: '42.00', quantity: 1 },\n user: { id: 'user-456' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://shop.example.com/products',\n },\n }),\n mapping: {\n name: 'add_to_cart',\n data: {\n map: {\n custom_data: {\n map: {\n value: 'data.price',\n currency: { value: 'EUR' },\n contents: {\n set: [\n {\n map: {\n id: 'data.id',\n item_name: 'data.name',\n item_price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n },\n },\n ],\n },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'add_to_cart',\n event_id: 'a1b2c3d4e5f60002',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n value: '42.00',\n currency: 'EUR',\n contents: [\n {\n id: 'SKU-B2',\n item_name: 'Cool Cap',\n item_price: '42.00',\n quantity: 1,\n },\n ],\n },\n event_source_url: 'https://shop.example.com/products',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const pageVisit: Flow.StepExample = {\n title: 'Page visit',\n description:\n 'A page view is sent to Pinterest as a page_visit conversion with the source URL.',\n in: getEvent('page view', {\n id: 'a1b2c3d4e5f60003',\n timestamp: 1700000902,\n user: { id: 'user-789' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/docs/',\n },\n }),\n mapping: {\n name: 'page_visit',\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'page_visit',\n event_id: 'a1b2c3d4e5f60003',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n event_source_url: 'https://www.example.com/docs/',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A site search event is forwarded to Pinterest as a search conversion with the query in custom data.',\n in: getEvent('entity action', {\n id: 'a1b2c3d4e5f60004',\n timestamp: 1700000903,\n name: 'site search',\n data: { query: 'walkerOS destinations' },\n user: { id: 'user-101' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/search',\n },\n }),\n mapping: {\n name: 'search',\n data: {\n map: {\n custom_data: {\n map: {\n search_string: 'data.query',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'search',\n event_id: 'a1b2c3d4e5f60004',\n event_time: 1700001,\n action_source: 'web',\n user_data: {},\n custom_data: {\n search_string: 'walkerOS destinations',\n },\n event_source_url: 'https://www.example.com/search',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const signup: Flow.StepExample = {\n title: 'Signup',\n description:\n 'A user signup is sent to Pinterest as a signup conversion with the hashed email and external id.',\n in: getEvent('entity action', {\n id: 'a1b2c3d4e5f60005',\n timestamp: 1700000904,\n name: 'user signup',\n data: { method: 'email' },\n user: { id: 'new-user-1', email: 'new@example.com' },\n source: {\n type: 'browser',\n platform: 'web',\n url: 'https://www.example.com/register',\n },\n }),\n mapping: {\n name: 'signup',\n data: {\n map: {\n user_data: {\n map: {\n em: { set: ['user.email'] },\n external_id: { set: ['user.id'] },\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n data: [\n {\n event_name: 'signup',\n event_id: 'a1b2c3d4e5f60005',\n event_time: 1700001,\n action_source: 'web',\n user_data: {\n // sha256('new@example.com')\n em: [\n 'f0030501023327437b06e5c6f87df7871b8e704ae608d1d0b7b24fdd2a06c716',\n ],\n // sha256('new-user-1')\n external_id: [\n 'b45cf5f6ebc2c6974ea3bd9fab19f8cc3a7cf63054727a9fcd22f1fda97d6dde',\n ],\n },\n event_source_url: 'https://www.example.com/register',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["z","z","z"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -10,6 +10,18 @@ interface Settings {
|
|
|
10
10
|
url?: string;
|
|
11
11
|
user_data?: Mapping$1.Map;
|
|
12
12
|
partner_name?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }.
|
|
15
|
+
* `false` switches it off.
|
|
16
|
+
* @default ['ingest.ip', 'event.user.ip']
|
|
17
|
+
*/
|
|
18
|
+
ip?: Mapping$1.Value | false;
|
|
19
|
+
/**
|
|
20
|
+
* Client user agent, sent as user_data.client_user_agent. Resolves against
|
|
21
|
+
* { ingest, event }. `false` switches it off.
|
|
22
|
+
* @default ['ingest.userAgent', 'event.user.userAgent']
|
|
23
|
+
*/
|
|
24
|
+
userAgent?: Mapping$1.Value | false;
|
|
13
25
|
}
|
|
14
26
|
type InitSettings = Partial<Settings>;
|
|
15
27
|
interface Mapping {
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,18 @@ interface Settings {
|
|
|
10
10
|
url?: string;
|
|
11
11
|
user_data?: Mapping$1.Map;
|
|
12
12
|
partner_name?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }.
|
|
15
|
+
* `false` switches it off.
|
|
16
|
+
* @default ['ingest.ip', 'event.user.ip']
|
|
17
|
+
*/
|
|
18
|
+
ip?: Mapping$1.Value | false;
|
|
19
|
+
/**
|
|
20
|
+
* Client user agent, sent as user_data.client_user_agent. Resolves against
|
|
21
|
+
* { ingest, event }. `false` switches it off.
|
|
22
|
+
* @default ['ingest.userAgent', 'event.user.userAgent']
|
|
23
|
+
*/
|
|
24
|
+
userAgent?: Mapping$1.Value | false;
|
|
13
25
|
}
|
|
14
26
|
type InitSettings = Partial<Settings>;
|
|
15
27
|
interface Mapping {
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var mod,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,index_exports={};((target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})})(index_exports,{DestinationPinterest:()=>types_exports,default:()=>index_default,destinationPinterest:()=>destinationPinterest}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core2=require("@walkeros/core"),import_server_core2=require("@walkeros/server-core"),import_core=require("@walkeros/core"),import_server_core=require("@walkeros/server-core"),keysToHash=["em","ph","fn","ln","db","ge","ct","st","zp","country","external_id","hashed_maids"];function shouldBeHashed(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}async function processValue(value,shouldHash){return shouldHash?(0,import_core.isArray)(value)?Promise.all(value.map(item=>(0,import_server_core.getHashServer)(String(item)))):(0,import_server_core.getHashServer)(String(value)):value}var push=async function(event,{config:config,data:data,env:env,logger:logger,collector:collector}){const{accessToken:accessToken,adAccountId:adAccountId,action_source:action_source="web",doNotHash:doNotHash,test:test,url:url="https://api.pinterest.com/v5/",user_data:user_data,partner_name:partner_name}=config.settings,eventData=(0,import_core2.isObject)(data)?data:{},configData=config.data?await(0,import_core2.getMappingValue)(event,config.data,{collector:collector}):{},userDataCustom=user_data?await(0,import_core2.getMappingValue)(event,{map:user_data},{collector:collector}):{},userData={...(0,import_core2.isObject)(configData)&&(0,import_core2.isObject)(configData.user_data)?configData.user_data:{},...(0,import_core2.isObject)(userDataCustom)?userDataCustom:{},...(0,import_core2.isObject)(eventData.user_data)?eventData.user_data:{}},{user_data:_ud,custom_data:eventCustomData,...restEventData}=eventData,serverEvent={event_name:event.name,event_id:event.id,event_time:Math.round((event.timestamp||Date.now())/1e3),action_source:action_source,...restEventData,user_data:userData};(0,import_core2.isObject)(eventCustomData)&&(serverEvent.custom_data=eventCustomData),"web"===action_source&&event.source?.url&&(serverEvent.event_source_url=event.source.url),partner_name&&(serverEvent.partner_name=partner_name);const hashedServerEvent=await async function(value,doNotHash=[]){if(!(0,import_core.isObject)(value))return value;const isUserData="user_data"in value,target=isUserData?value.user_data:value,result=(await Promise.all(Object.entries(target).map(async([k,v])=>[k,await processValue(v,isUserData&&shouldBeHashed(k,doNotHash))]))).reduce((acc,[k,v])=>((0,import_core.isString)(k)&&(acc[k]=v),acc),{});return isUserData?{...value,user_data:result}:result}(serverEvent,doNotHash),body={data:[hashedServerEvent]},endpoint=`${url}ad_accounts/${adAccountId}/events${test?"?test=true":""}`;logger.debug("Calling Pinterest API",{endpoint:endpoint,method:"POST",eventName:serverEvent.event_name,eventId:serverEvent.event_id});const sendServerFn=env?.sendServer||import_server_core2.sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`}});logger.debug("Pinterest API response",{ok:!(0,import_core2.isObject)(result)||result.ok}),(0,import_core2.isObject)(result)&&!1===result.ok&&logger.throw(`Pinterest API error: ${JSON.stringify(result)}`)},types_exports={},destinationPinterest={type:"pinterest",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,adAccountId:adAccountId}=settings;accessToken||logger.throw("Config settings accessToken missing"),adAccountId||logger.throw("Config settings adAccountId missing");const settingsConfig={...settings,accessToken:accessToken,adAccountId:adAccountId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await push(event,context)},index_default=destinationPinterest;//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";var mod,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,index_exports={};((target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})})(index_exports,{DestinationPinterest:()=>types_exports,default:()=>index_default,destinationPinterest:()=>destinationPinterest}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core2=require("@walkeros/core"),import_server_core2=require("@walkeros/server-core"),import_core=require("@walkeros/core"),import_server_core=require("@walkeros/server-core"),keysToHash=["em","ph","fn","ln","db","ge","ct","st","zp","country","external_id","hashed_maids"];function shouldBeHashed(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}async function processValue(value,shouldHash){return shouldHash?(0,import_core.isArray)(value)?Promise.all(value.map(item=>(0,import_server_core.getHashServer)(String(item)))):(0,import_server_core.getHashServer)(String(value)):value}var push=async function(event,{config:config,data:data,ingest:ingest,env:env,logger:logger,collector:collector}){const{accessToken:accessToken,adAccountId:adAccountId,action_source:action_source="web",doNotHash:doNotHash,test:test,url:url="https://api.pinterest.com/v5/",user_data:user_data,partner_name:partner_name,ip:ip,userAgent:userAgent}=config.settings,eventData=(0,import_core2.isObject)(data)?data:{},configData=config.data?await(0,import_core2.getMappingValue)(event,config.data,{collector:collector}):{},userDataCustom=user_data?await(0,import_core2.getMappingValue)(event,{map:user_data},{collector:collector}):{},root=(0,import_core2.createMappingRoot)(ingest,event),clientIp=await resolveClient(ip,DEFAULT_IP,root,collector),clientUserAgent=await resolveClient(userAgent,DEFAULT_USER_AGENT,root,collector),userData={...void 0!==clientIp?{client_ip_address:clientIp}:{},...void 0!==clientUserAgent?{client_user_agent:clientUserAgent}:{},...(0,import_core2.isObject)(configData)&&(0,import_core2.isObject)(configData.user_data)?configData.user_data:{},...(0,import_core2.isObject)(userDataCustom)?userDataCustom:{},...(0,import_core2.isObject)(eventData.user_data)?eventData.user_data:{}},{user_data:_ud,custom_data:eventCustomData,...restEventData}=eventData,serverEvent={event_name:event.name,event_id:event.id,event_time:Math.round((event.timestamp||Date.now())/1e3),action_source:action_source,...restEventData,user_data:userData};(0,import_core2.isObject)(eventCustomData)&&(serverEvent.custom_data=eventCustomData),"web"===action_source&&event.source?.url&&(serverEvent.event_source_url=event.source.url),partner_name&&(serverEvent.partner_name=partner_name);const hashedServerEvent=await async function(value,doNotHash=[]){if(!(0,import_core.isObject)(value))return value;const isUserData="user_data"in value,target=isUserData?value.user_data:value,result=(await Promise.all(Object.entries(target).map(async([k,v])=>[k,await processValue(v,isUserData&&shouldBeHashed(k,doNotHash))]))).reduce((acc,[k,v])=>((0,import_core.isString)(k)&&(acc[k]=v),acc),{});return isUserData?{...value,user_data:result}:result}(serverEvent,doNotHash),body={data:[hashedServerEvent]},endpoint=`${url}ad_accounts/${adAccountId}/events${test?"?test=true":""}`;logger.debug("Calling Pinterest API",{endpoint:endpoint,method:"POST",eventName:serverEvent.event_name,eventId:serverEvent.event_id});const sendServerFn=env?.sendServer||import_server_core2.sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`}});logger.debug("Pinterest API response",{ok:!(0,import_core2.isObject)(result)||result.ok}),(0,import_core2.isObject)(result)&&!1===result.ok&&logger.throw(`Pinterest API error: ${JSON.stringify(result)}`)},DEFAULT_IP=["ingest.ip","event.user.ip"],DEFAULT_USER_AGENT=["ingest.userAgent","event.user.userAgent"];async function resolveClient(setting,fallback,root,collector){if(!1===setting)return;const value=await(0,import_core2.getMappingValue)(root,setting??fallback,{collector:collector});return"string"==typeof value&&""!==value?value:void 0}var types_exports={},destinationPinterest={type:"pinterest",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,adAccountId:adAccountId}=settings;accessToken||logger.throw("Config settings accessToken missing"),adAccountId||logger.throw("Config settings adAccountId missing");const settingsConfig={...settings,accessToken:accessToken,adAccountId:adAccountId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await push(event,context)},index_default=destinationPinterest;//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts"],"sourcesContent":["import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationPinterest from './types';\n\nexport const destinationPinterest: Destination = {\n type: 'pinterest',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationPinterest;\n","import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, adAccountId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!adAccountId) logger.throw('Config settings adAccountId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n adAccountId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { ConversionEvent, PushFn, RequestBody, UserData } from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEvent } from './hash';\n\nexport const push: PushFn = async function (\n event,\n { config, data, env, logger, collector },\n) {\n const {\n accessToken,\n adAccountId,\n action_source = 'web',\n doNotHash,\n test,\n url = 'https://api.pinterest.com/v5/',\n user_data,\n partner_name,\n } = config.settings!;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data, { collector })\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data }, { collector })\n : {};\n\n // Merge user_data from config.data, settings.user_data, and event mapping\n const userData: UserData = {\n // Destination config\n ...(isObject(configData) && isObject(configData.user_data)\n ? configData.user_data\n : {}),\n // Custom user_data from settings\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n // Event mapping\n ...(isObject(eventData.user_data) ? eventData.user_data : {}),\n };\n\n // Extract custom_data and user_data from eventData, leave the rest\n const {\n user_data: _ud,\n custom_data: eventCustomData,\n ...restEventData\n } = eventData;\n\n const serverEvent: ConversionEvent = {\n event_name: event.name,\n event_id: event.id,\n event_time: Math.round((event.timestamp || Date.now()) / 1000),\n action_source,\n ...restEventData,\n user_data: userData,\n };\n\n // Nest custom_data from mapping\n if (isObject(eventCustomData)) {\n serverEvent.custom_data = eventCustomData as ConversionEvent['custom_data'];\n }\n\n // Set event_source_url for web events\n if (action_source === 'web' && event.source?.url) {\n serverEvent.event_source_url = event.source.url;\n }\n\n // Add partner_name from settings\n if (partner_name) {\n serverEvent.partner_name = partner_name;\n }\n\n const hashedServerEvent = await hashEvent(serverEvent, doNotHash);\n\n const body: RequestBody = { data: [hashedServerEvent] };\n\n // Build endpoint URL\n const testParam = test ? '?test=true' : '';\n const endpoint = `${url}ad_accounts/${adAccountId}/events${testParam}`;\n\n logger.debug('Calling Pinterest API', {\n endpoint,\n method: 'POST',\n eventName: serverEvent.event_name,\n eventId: serverEvent.event_id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n logger.debug('Pinterest API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Pinterest API error: ${JSON.stringify(result)}`);\n }\n};\n","import { WalkerOS } from '@walkeros/core';\nimport { isArray, isObject, isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\nconst keysToHash = [\n 'em',\n 'ph',\n 'fn',\n 'ln',\n 'db',\n 'ge',\n 'ct',\n 'st',\n 'zp',\n 'country',\n 'external_id',\n 'hashed_maids',\n];\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\ntype HashableValue = WalkerOS.AnyObject | unknown | unknown[];\n\nasync function processValue(\n value: unknown,\n shouldHash: boolean,\n): Promise<unknown> {\n if (!shouldHash) return value;\n if (isArray(value)) {\n return Promise.all(value.map((item) => getHashServer(String(item))));\n }\n return getHashServer(String(value));\n}\n\nexport async function hashEvent<T extends HashableValue>(\n value: T,\n doNotHash: string[] = [],\n): Promise<T> {\n if (!isObject(value)) return value;\n\n const isUserData = 'user_data' in value;\n const target = (isUserData ? value.user_data : value) as WalkerOS.AnyObject;\n\n const entries = await Promise.all(\n Object.entries(target).map(async ([k, v]) => [\n k,\n await processValue(v, isUserData && shouldBeHashed(k, doNotHash)),\n ]),\n );\n\n const result = entries.reduce((acc, [k, v]) => {\n if (isString(k)) acc[k] = v;\n return acc;\n }, {} as WalkerOS.AnyObject);\n\n return isUserData ? { ...value, user_data: result } : (result as T);\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n adAccountId: string;\n action_source?: ActionSource;\n doNotHash?: string[];\n test?: boolean;\n url?: string;\n user_data?: WalkerOSMapping.Map;\n partner_name?: string;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// Pinterest Conversions API types\n// https://developers.pinterest.com/docs/conversions/conversions/\n\nexport type ActionSource = 'app_android' | 'app_ios' | 'web' | 'offline';\n\nexport type EventName =\n | 'add_payment_info'\n | 'add_to_cart'\n | 'add_to_wishlist'\n | 'app_install'\n | 'app_open'\n | 'checkout'\n | 'contact'\n | 'custom'\n | 'customize_product'\n | 'find_location'\n | 'initiate_checkout'\n | 'lead'\n | 'page_visit'\n | 'schedule'\n | 'search'\n | 'signup'\n | 'start_trial'\n | 'submit_application'\n | 'subscribe'\n | 'view_category'\n | 'view_content'\n | 'watch_video'\n | string;\n\nexport interface ConversionEvent {\n // Required\n event_name: EventName;\n event_time: number;\n event_id: string;\n action_source: ActionSource;\n user_data: UserData;\n\n // Optional\n event_source_url?: string;\n opt_out?: boolean;\n partner_name?: string;\n app_id?: string;\n app_name?: string;\n app_version?: string;\n device_brand?: string;\n device_carrier?: string;\n device_model?: string;\n device_type?: string;\n os_version?: string;\n language?: string;\n wifi?: boolean;\n custom_data?: CustomData;\n}\n\nexport interface UserData {\n // Hashable fields (SHA-256, arrays)\n em?: string[];\n ph?: string[];\n fn?: string[];\n ln?: string[];\n db?: string[];\n ge?: string[];\n ct?: string[];\n st?: string[];\n zp?: string[];\n country?: string[];\n external_id?: string[];\n hashed_maids?: string[];\n\n // Pass-through fields (do NOT hash)\n client_ip_address?: string;\n client_user_agent?: string;\n click_id?: string;\n partner_id?: string;\n}\n\nexport interface CustomData {\n currency?: string;\n value?: string;\n content_ids?: string[];\n content_name?: string;\n content_category?: string;\n content_brand?: string;\n contents?: ContentItem[];\n num_items?: number;\n order_id?: string;\n search_string?: string;\n opt_out_type?: string;\n np?: string;\n predicted_ltv?: string;\n}\n\nexport interface ContentItem {\n id?: string;\n item_name?: string;\n item_category?: string;\n item_brand?: string;\n item_price?: string;\n quantity?: number;\n}\n\nexport interface RequestBody {\n data: ConversionEvent[];\n}\n\nexport interface ResponseBody {\n num_events_received: number;\n num_events_processed: number;\n events: Array<{\n status: string;\n error_message?: string;\n warning_message?: string;\n }>;\n}\n"],"mappings":"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","names":["import_core","import_server_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts"],"sourcesContent":["import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationPinterest from './types';\n\nexport const destinationPinterest: Destination = {\n type: 'pinterest',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationPinterest;\n","import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, adAccountId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!adAccountId) logger.throw('Config settings adAccountId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n adAccountId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { ConversionEvent, PushFn, RequestBody, UserData } from './types';\nimport type { Collector, Mapping as WalkerOSMapping } from '@walkeros/core';\nimport { createMappingRoot, getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEvent } from './hash';\n\nexport const push: PushFn = async function (\n event,\n { config, data, ingest, env, logger, collector },\n) {\n const {\n accessToken,\n adAccountId,\n action_source = 'web',\n doNotHash,\n test,\n url = 'https://api.pinterest.com/v5/',\n user_data,\n partner_name,\n ip,\n userAgent,\n } = config.settings!;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data, { collector })\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data }, { collector })\n : {};\n\n // Merge user_data from config.data, settings.user_data, and event mapping\n // Client IP and user agent auto-fill, overridden by any mapped value\n const root = createMappingRoot(ingest, event);\n const clientIp = await resolveClient(ip, DEFAULT_IP, root, collector);\n const clientUserAgent = await resolveClient(\n userAgent,\n DEFAULT_USER_AGENT,\n root,\n collector,\n );\n\n const userData: UserData = {\n ...(clientIp !== undefined ? { client_ip_address: clientIp } : {}),\n ...(clientUserAgent !== undefined\n ? { client_user_agent: clientUserAgent }\n : {}),\n // Destination config\n ...(isObject(configData) && isObject(configData.user_data)\n ? configData.user_data\n : {}),\n // Custom user_data from settings\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n // Event mapping\n ...(isObject(eventData.user_data) ? eventData.user_data : {}),\n };\n\n // Extract custom_data and user_data from eventData, leave the rest\n const {\n user_data: _ud,\n custom_data: eventCustomData,\n ...restEventData\n } = eventData;\n\n const serverEvent: ConversionEvent = {\n event_name: event.name,\n event_id: event.id,\n event_time: Math.round((event.timestamp || Date.now()) / 1000),\n action_source,\n ...restEventData,\n user_data: userData,\n };\n\n // Nest custom_data from mapping\n if (isObject(eventCustomData)) {\n serverEvent.custom_data = eventCustomData as ConversionEvent['custom_data'];\n }\n\n // Set event_source_url for web events\n if (action_source === 'web' && event.source?.url) {\n serverEvent.event_source_url = event.source.url;\n }\n\n // Add partner_name from settings\n if (partner_name) {\n serverEvent.partner_name = partner_name;\n }\n\n const hashedServerEvent = await hashEvent(serverEvent, doNotHash);\n\n const body: RequestBody = { data: [hashedServerEvent] };\n\n // Build endpoint URL\n const testParam = test ? '?test=true' : '';\n const endpoint = `${url}ad_accounts/${adAccountId}/events${testParam}`;\n\n logger.debug('Calling Pinterest API', {\n endpoint,\n method: 'POST',\n eventName: serverEvent.event_name,\n eventId: serverEvent.event_id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n logger.debug('Pinterest API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Pinterest API error: ${JSON.stringify(result)}`);\n }\n};\n\nconst DEFAULT_IP: WalkerOSMapping.Value = ['ingest.ip', 'event.user.ip'];\nconst DEFAULT_USER_AGENT: WalkerOSMapping.Value = [\n 'ingest.userAgent',\n 'event.user.userAgent',\n];\n\n/** A client IP or user agent setting resolved to a non-empty string. */\nasync function resolveClient(\n setting: WalkerOSMapping.Value | false | undefined,\n fallback: WalkerOSMapping.Value,\n root: WalkerOSMapping.Root,\n collector: Collector.Instance,\n): Promise<string | undefined> {\n if (setting === false) return undefined;\n const value = await getMappingValue(root, setting ?? fallback, { collector });\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n","import { WalkerOS } from '@walkeros/core';\nimport { isArray, isObject, isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\nconst keysToHash = [\n 'em',\n 'ph',\n 'fn',\n 'ln',\n 'db',\n 'ge',\n 'ct',\n 'st',\n 'zp',\n 'country',\n 'external_id',\n 'hashed_maids',\n];\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\ntype HashableValue = WalkerOS.AnyObject | unknown | unknown[];\n\nasync function processValue(\n value: unknown,\n shouldHash: boolean,\n): Promise<unknown> {\n if (!shouldHash) return value;\n if (isArray(value)) {\n return Promise.all(value.map((item) => getHashServer(String(item))));\n }\n return getHashServer(String(value));\n}\n\nexport async function hashEvent<T extends HashableValue>(\n value: T,\n doNotHash: string[] = [],\n): Promise<T> {\n if (!isObject(value)) return value;\n\n const isUserData = 'user_data' in value;\n const target = (isUserData ? value.user_data : value) as WalkerOS.AnyObject;\n\n const entries = await Promise.all(\n Object.entries(target).map(async ([k, v]) => [\n k,\n await processValue(v, isUserData && shouldBeHashed(k, doNotHash)),\n ]),\n );\n\n const result = entries.reduce((acc, [k, v]) => {\n if (isString(k)) acc[k] = v;\n return acc;\n }, {} as WalkerOS.AnyObject);\n\n return isUserData ? { ...value, user_data: result } : (result as T);\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n adAccountId: string;\n action_source?: ActionSource;\n doNotHash?: string[];\n test?: boolean;\n url?: string;\n user_data?: WalkerOSMapping.Map;\n partner_name?: string;\n /**\n * Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }.\n * `false` switches it off.\n * @default ['ingest.ip', 'event.user.ip']\n */\n ip?: WalkerOSMapping.Value | false;\n /**\n * Client user agent, sent as user_data.client_user_agent. Resolves against\n * { ingest, event }. `false` switches it off.\n * @default ['ingest.userAgent', 'event.user.userAgent']\n */\n userAgent?: WalkerOSMapping.Value | false;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// Pinterest Conversions API types\n// https://developers.pinterest.com/docs/conversions/conversions/\n\nexport type ActionSource = 'app_android' | 'app_ios' | 'web' | 'offline';\n\nexport type EventName =\n | 'add_payment_info'\n | 'add_to_cart'\n | 'add_to_wishlist'\n | 'app_install'\n | 'app_open'\n | 'checkout'\n | 'contact'\n | 'custom'\n | 'customize_product'\n | 'find_location'\n | 'initiate_checkout'\n | 'lead'\n | 'page_visit'\n | 'schedule'\n | 'search'\n | 'signup'\n | 'start_trial'\n | 'submit_application'\n | 'subscribe'\n | 'view_category'\n | 'view_content'\n | 'watch_video'\n | string;\n\nexport interface ConversionEvent {\n // Required\n event_name: EventName;\n event_time: number;\n event_id: string;\n action_source: ActionSource;\n user_data: UserData;\n\n // Optional\n event_source_url?: string;\n opt_out?: boolean;\n partner_name?: string;\n app_id?: string;\n app_name?: string;\n app_version?: string;\n device_brand?: string;\n device_carrier?: string;\n device_model?: string;\n device_type?: string;\n os_version?: string;\n language?: string;\n wifi?: boolean;\n custom_data?: CustomData;\n}\n\nexport interface UserData {\n // Hashable fields (SHA-256, arrays)\n em?: string[];\n ph?: string[];\n fn?: string[];\n ln?: string[];\n db?: string[];\n ge?: string[];\n ct?: string[];\n st?: string[];\n zp?: string[];\n country?: string[];\n external_id?: string[];\n hashed_maids?: string[];\n\n // Pass-through fields (do NOT hash)\n client_ip_address?: string;\n client_user_agent?: string;\n click_id?: string;\n partner_id?: string;\n}\n\nexport interface CustomData {\n currency?: string;\n value?: string;\n content_ids?: string[];\n content_name?: string;\n content_category?: string;\n content_brand?: string;\n contents?: ContentItem[];\n num_items?: number;\n order_id?: string;\n search_string?: string;\n opt_out_type?: string;\n np?: string;\n predicted_ltv?: string;\n}\n\nexport interface ContentItem {\n id?: string;\n item_name?: string;\n item_category?: string;\n item_brand?: string;\n item_price?: string;\n quantity?: number;\n}\n\nexport interface RequestBody {\n data: ConversionEvent[];\n}\n\nexport interface ResponseBody {\n num_events_received: number;\n num_events_processed: number;\n events: Array<{\n status: string;\n error_message?: string;\n warning_message?: string;\n }>;\n}\n"],"mappings":"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","names":["import_core","import_server_core"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getMappingValue,isObject as isObject2}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{isArray,isObject,isString}from"@walkeros/core";import{getHashServer}from"@walkeros/server-core";var keysToHash=["em","ph","fn","ln","db","ge","ct","st","zp","country","external_id","hashed_maids"];function shouldBeHashed(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}async function processValue(value,shouldHash){return shouldHash?isArray(value)?Promise.all(value.map(item=>getHashServer(String(item)))):getHashServer(String(value)):value}var push=async function(event,{config:config,data:data,env:env,logger:logger,collector:collector}){const{accessToken:accessToken,adAccountId:adAccountId,action_source:action_source="web",doNotHash:doNotHash,test:test,url:url="https://api.pinterest.com/v5/",user_data:user_data,partner_name:partner_name}=config.settings,eventData=isObject2(data)?data:{},configData=config.data?await getMappingValue(event,config.data,{collector:collector}):{},userDataCustom=user_data?await getMappingValue(event,{map:user_data},{collector:collector}):{},userData={...isObject2(configData)&&isObject2(configData.user_data)?configData.user_data:{},...isObject2(userDataCustom)?userDataCustom:{},...isObject2(eventData.user_data)?eventData.user_data:{}},{user_data:_ud,custom_data:eventCustomData,...restEventData}=eventData,serverEvent={event_name:event.name,event_id:event.id,event_time:Math.round((event.timestamp||Date.now())/1e3),action_source:action_source,...restEventData,user_data:userData};isObject2(eventCustomData)&&(serverEvent.custom_data=eventCustomData),"web"===action_source&&event.source?.url&&(serverEvent.event_source_url=event.source.url),partner_name&&(serverEvent.partner_name=partner_name);const hashedServerEvent=await async function(value,doNotHash=[]){if(!isObject(value))return value;const isUserData="user_data"in value,target=isUserData?value.user_data:value,result=(await Promise.all(Object.entries(target).map(async([k,v])=>[k,await processValue(v,isUserData&&shouldBeHashed(k,doNotHash))]))).reduce((acc,[k,v])=>(isString(k)&&(acc[k]=v),acc),{});return isUserData?{...value,user_data:result}:result}(serverEvent,doNotHash),body={data:[hashedServerEvent]},endpoint=`${url}ad_accounts/${adAccountId}/events${test?"?test=true":""}`;logger.debug("Calling Pinterest API",{endpoint:endpoint,method:"POST",eventName:serverEvent.event_name,eventId:serverEvent.event_id});const sendServerFn=env?.sendServer||sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`}});logger.debug("Pinterest API response",{ok:!isObject2(result)||result.ok}),isObject2(result)&&!1===result.ok&&logger.throw(`Pinterest API error: ${JSON.stringify(result)}`)},types_exports={},destinationPinterest={type:"pinterest",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,adAccountId:adAccountId}=settings;accessToken||logger.throw("Config settings accessToken missing"),adAccountId||logger.throw("Config settings adAccountId missing");const settingsConfig={...settings,accessToken:accessToken,adAccountId:adAccountId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await push(event,context)},index_default=destinationPinterest;export{types_exports as DestinationPinterest,index_default as default,destinationPinterest};//# sourceMappingURL=index.mjs.map
|
|
1
|
+
import{createMappingRoot,getMappingValue,isObject as isObject2}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{isArray,isObject,isString}from"@walkeros/core";import{getHashServer}from"@walkeros/server-core";var keysToHash=["em","ph","fn","ln","db","ge","ct","st","zp","country","external_id","hashed_maids"];function shouldBeHashed(key,doNotHash=[]){return keysToHash.includes(key)&&!doNotHash.includes(key)}async function processValue(value,shouldHash){return shouldHash?isArray(value)?Promise.all(value.map(item=>getHashServer(String(item)))):getHashServer(String(value)):value}var push=async function(event,{config:config,data:data,ingest:ingest,env:env,logger:logger,collector:collector}){const{accessToken:accessToken,adAccountId:adAccountId,action_source:action_source="web",doNotHash:doNotHash,test:test,url:url="https://api.pinterest.com/v5/",user_data:user_data,partner_name:partner_name,ip:ip,userAgent:userAgent}=config.settings,eventData=isObject2(data)?data:{},configData=config.data?await getMappingValue(event,config.data,{collector:collector}):{},userDataCustom=user_data?await getMappingValue(event,{map:user_data},{collector:collector}):{},root=createMappingRoot(ingest,event),clientIp=await resolveClient(ip,DEFAULT_IP,root,collector),clientUserAgent=await resolveClient(userAgent,DEFAULT_USER_AGENT,root,collector),userData={...void 0!==clientIp?{client_ip_address:clientIp}:{},...void 0!==clientUserAgent?{client_user_agent:clientUserAgent}:{},...isObject2(configData)&&isObject2(configData.user_data)?configData.user_data:{},...isObject2(userDataCustom)?userDataCustom:{},...isObject2(eventData.user_data)?eventData.user_data:{}},{user_data:_ud,custom_data:eventCustomData,...restEventData}=eventData,serverEvent={event_name:event.name,event_id:event.id,event_time:Math.round((event.timestamp||Date.now())/1e3),action_source:action_source,...restEventData,user_data:userData};isObject2(eventCustomData)&&(serverEvent.custom_data=eventCustomData),"web"===action_source&&event.source?.url&&(serverEvent.event_source_url=event.source.url),partner_name&&(serverEvent.partner_name=partner_name);const hashedServerEvent=await async function(value,doNotHash=[]){if(!isObject(value))return value;const isUserData="user_data"in value,target=isUserData?value.user_data:value,result=(await Promise.all(Object.entries(target).map(async([k,v])=>[k,await processValue(v,isUserData&&shouldBeHashed(k,doNotHash))]))).reduce((acc,[k,v])=>(isString(k)&&(acc[k]=v),acc),{});return isUserData?{...value,user_data:result}:result}(serverEvent,doNotHash),body={data:[hashedServerEvent]},endpoint=`${url}ad_accounts/${adAccountId}/events${test?"?test=true":""}`;logger.debug("Calling Pinterest API",{endpoint:endpoint,method:"POST",eventName:serverEvent.event_name,eventId:serverEvent.event_id});const sendServerFn=env?.sendServer||sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`}});logger.debug("Pinterest API response",{ok:!isObject2(result)||result.ok}),isObject2(result)&&!1===result.ok&&logger.throw(`Pinterest API error: ${JSON.stringify(result)}`)},DEFAULT_IP=["ingest.ip","event.user.ip"],DEFAULT_USER_AGENT=["ingest.userAgent","event.user.userAgent"];async function resolveClient(setting,fallback,root,collector){if(!1===setting)return;const value=await getMappingValue(root,setting??fallback,{collector:collector});return"string"==typeof value&&""!==value?value:void 0}var types_exports={},destinationPinterest={type:"pinterest",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,adAccountId:adAccountId}=settings;accessToken||logger.throw("Config settings accessToken missing"),adAccountId||logger.throw("Config settings adAccountId missing");const settingsConfig={...settings,accessToken:accessToken,adAccountId:adAccountId};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await push(event,context)},index_default=destinationPinterest;export{types_exports as DestinationPinterest,index_default as default,destinationPinterest};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, adAccountId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!adAccountId) logger.throw('Config settings adAccountId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n adAccountId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { ConversionEvent, PushFn, RequestBody, UserData } from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEvent } from './hash';\n\nexport const push: PushFn = async function (\n event,\n { config, data, env, logger, collector },\n) {\n const {\n accessToken,\n adAccountId,\n action_source = 'web',\n doNotHash,\n test,\n url = 'https://api.pinterest.com/v5/',\n user_data,\n partner_name,\n } = config.settings!;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data, { collector })\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data }, { collector })\n : {};\n\n // Merge user_data from config.data, settings.user_data, and event mapping\n const userData: UserData = {\n // Destination config\n ...(isObject(configData) && isObject(configData.user_data)\n ? configData.user_data\n : {}),\n // Custom user_data from settings\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n // Event mapping\n ...(isObject(eventData.user_data) ? eventData.user_data : {}),\n };\n\n // Extract custom_data and user_data from eventData, leave the rest\n const {\n user_data: _ud,\n custom_data: eventCustomData,\n ...restEventData\n } = eventData;\n\n const serverEvent: ConversionEvent = {\n event_name: event.name,\n event_id: event.id,\n event_time: Math.round((event.timestamp || Date.now()) / 1000),\n action_source,\n ...restEventData,\n user_data: userData,\n };\n\n // Nest custom_data from mapping\n if (isObject(eventCustomData)) {\n serverEvent.custom_data = eventCustomData as ConversionEvent['custom_data'];\n }\n\n // Set event_source_url for web events\n if (action_source === 'web' && event.source?.url) {\n serverEvent.event_source_url = event.source.url;\n }\n\n // Add partner_name from settings\n if (partner_name) {\n serverEvent.partner_name = partner_name;\n }\n\n const hashedServerEvent = await hashEvent(serverEvent, doNotHash);\n\n const body: RequestBody = { data: [hashedServerEvent] };\n\n // Build endpoint URL\n const testParam = test ? '?test=true' : '';\n const endpoint = `${url}ad_accounts/${adAccountId}/events${testParam}`;\n\n logger.debug('Calling Pinterest API', {\n endpoint,\n method: 'POST',\n eventName: serverEvent.event_name,\n eventId: serverEvent.event_id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n logger.debug('Pinterest API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Pinterest API error: ${JSON.stringify(result)}`);\n }\n};\n","import { WalkerOS } from '@walkeros/core';\nimport { isArray, isObject, isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\nconst keysToHash = [\n 'em',\n 'ph',\n 'fn',\n 'ln',\n 'db',\n 'ge',\n 'ct',\n 'st',\n 'zp',\n 'country',\n 'external_id',\n 'hashed_maids',\n];\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\ntype HashableValue = WalkerOS.AnyObject | unknown | unknown[];\n\nasync function processValue(\n value: unknown,\n shouldHash: boolean,\n): Promise<unknown> {\n if (!shouldHash) return value;\n if (isArray(value)) {\n return Promise.all(value.map((item) => getHashServer(String(item))));\n }\n return getHashServer(String(value));\n}\n\nexport async function hashEvent<T extends HashableValue>(\n value: T,\n doNotHash: string[] = [],\n): Promise<T> {\n if (!isObject(value)) return value;\n\n const isUserData = 'user_data' in value;\n const target = (isUserData ? value.user_data : value) as WalkerOS.AnyObject;\n\n const entries = await Promise.all(\n Object.entries(target).map(async ([k, v]) => [\n k,\n await processValue(v, isUserData && shouldBeHashed(k, doNotHash)),\n ]),\n );\n\n const result = entries.reduce((acc, [k, v]) => {\n if (isString(k)) acc[k] = v;\n return acc;\n }, {} as WalkerOS.AnyObject);\n\n return isUserData ? { ...value, user_data: result } : (result as T);\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n adAccountId: string;\n action_source?: ActionSource;\n doNotHash?: string[];\n test?: boolean;\n url?: string;\n user_data?: WalkerOSMapping.Map;\n partner_name?: string;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// Pinterest Conversions API types\n// https://developers.pinterest.com/docs/conversions/conversions/\n\nexport type ActionSource = 'app_android' | 'app_ios' | 'web' | 'offline';\n\nexport type EventName =\n | 'add_payment_info'\n | 'add_to_cart'\n | 'add_to_wishlist'\n | 'app_install'\n | 'app_open'\n | 'checkout'\n | 'contact'\n | 'custom'\n | 'customize_product'\n | 'find_location'\n | 'initiate_checkout'\n | 'lead'\n | 'page_visit'\n | 'schedule'\n | 'search'\n | 'signup'\n | 'start_trial'\n | 'submit_application'\n | 'subscribe'\n | 'view_category'\n | 'view_content'\n | 'watch_video'\n | string;\n\nexport interface ConversionEvent {\n // Required\n event_name: EventName;\n event_time: number;\n event_id: string;\n action_source: ActionSource;\n user_data: UserData;\n\n // Optional\n event_source_url?: string;\n opt_out?: boolean;\n partner_name?: string;\n app_id?: string;\n app_name?: string;\n app_version?: string;\n device_brand?: string;\n device_carrier?: string;\n device_model?: string;\n device_type?: string;\n os_version?: string;\n language?: string;\n wifi?: boolean;\n custom_data?: CustomData;\n}\n\nexport interface UserData {\n // Hashable fields (SHA-256, arrays)\n em?: string[];\n ph?: string[];\n fn?: string[];\n ln?: string[];\n db?: string[];\n ge?: string[];\n ct?: string[];\n st?: string[];\n zp?: string[];\n country?: string[];\n external_id?: string[];\n hashed_maids?: string[];\n\n // Pass-through fields (do NOT hash)\n client_ip_address?: string;\n client_user_agent?: string;\n click_id?: string;\n partner_id?: string;\n}\n\nexport interface CustomData {\n currency?: string;\n value?: string;\n content_ids?: string[];\n content_name?: string;\n content_category?: string;\n content_brand?: string;\n contents?: ContentItem[];\n num_items?: number;\n order_id?: string;\n search_string?: string;\n opt_out_type?: string;\n np?: string;\n predicted_ltv?: string;\n}\n\nexport interface ContentItem {\n id?: string;\n item_name?: string;\n item_category?: string;\n item_brand?: string;\n item_price?: string;\n quantity?: number;\n}\n\nexport interface RequestBody {\n data: ConversionEvent[];\n}\n\nexport interface ResponseBody {\n num_events_received: number;\n num_events_processed: number;\n events: Array<{\n status: string;\n error_message?: string;\n warning_message?: string;\n }>;\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationPinterest from './types';\n\nexport const destinationPinterest: Destination = {\n type: 'pinterest',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationPinterest;\n"],"mappings":"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","names":["isObject","isObject"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/push.ts","../src/hash.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type { Config, Settings, PartialConfig } from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n partialConfig: PartialConfig = {},\n logger: Logger.Instance,\n): Config {\n const settings = (partialConfig.settings || {}) as Partial<Settings>;\n const { accessToken, adAccountId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!adAccountId) logger.throw('Config settings adAccountId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n adAccountId,\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type { ConversionEvent, PushFn, RequestBody, UserData } from './types';\nimport type { Collector, Mapping as WalkerOSMapping } from '@walkeros/core';\nimport { createMappingRoot, getMappingValue, isObject } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { hashEvent } from './hash';\n\nexport const push: PushFn = async function (\n event,\n { config, data, ingest, env, logger, collector },\n) {\n const {\n accessToken,\n adAccountId,\n action_source = 'web',\n doNotHash,\n test,\n url = 'https://api.pinterest.com/v5/',\n user_data,\n partner_name,\n ip,\n userAgent,\n } = config.settings!;\n\n const eventData = isObject(data) ? data : {};\n const configData = config.data\n ? await getMappingValue(event, config.data, { collector })\n : {};\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data }, { collector })\n : {};\n\n // Merge user_data from config.data, settings.user_data, and event mapping\n // Client IP and user agent auto-fill, overridden by any mapped value\n const root = createMappingRoot(ingest, event);\n const clientIp = await resolveClient(ip, DEFAULT_IP, root, collector);\n const clientUserAgent = await resolveClient(\n userAgent,\n DEFAULT_USER_AGENT,\n root,\n collector,\n );\n\n const userData: UserData = {\n ...(clientIp !== undefined ? { client_ip_address: clientIp } : {}),\n ...(clientUserAgent !== undefined\n ? { client_user_agent: clientUserAgent }\n : {}),\n // Destination config\n ...(isObject(configData) && isObject(configData.user_data)\n ? configData.user_data\n : {}),\n // Custom user_data from settings\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n // Event mapping\n ...(isObject(eventData.user_data) ? eventData.user_data : {}),\n };\n\n // Extract custom_data and user_data from eventData, leave the rest\n const {\n user_data: _ud,\n custom_data: eventCustomData,\n ...restEventData\n } = eventData;\n\n const serverEvent: ConversionEvent = {\n event_name: event.name,\n event_id: event.id,\n event_time: Math.round((event.timestamp || Date.now()) / 1000),\n action_source,\n ...restEventData,\n user_data: userData,\n };\n\n // Nest custom_data from mapping\n if (isObject(eventCustomData)) {\n serverEvent.custom_data = eventCustomData as ConversionEvent['custom_data'];\n }\n\n // Set event_source_url for web events\n if (action_source === 'web' && event.source?.url) {\n serverEvent.event_source_url = event.source.url;\n }\n\n // Add partner_name from settings\n if (partner_name) {\n serverEvent.partner_name = partner_name;\n }\n\n const hashedServerEvent = await hashEvent(serverEvent, doNotHash);\n\n const body: RequestBody = { data: [hashedServerEvent] };\n\n // Build endpoint URL\n const testParam = test ? '?test=true' : '';\n const endpoint = `${url}ad_accounts/${adAccountId}/events${testParam}`;\n\n logger.debug('Calling Pinterest API', {\n endpoint,\n method: 'POST',\n eventName: serverEvent.event_name,\n eventId: serverEvent.event_id,\n });\n\n const sendServerFn = env?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n logger.debug('Pinterest API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`Pinterest API error: ${JSON.stringify(result)}`);\n }\n};\n\nconst DEFAULT_IP: WalkerOSMapping.Value = ['ingest.ip', 'event.user.ip'];\nconst DEFAULT_USER_AGENT: WalkerOSMapping.Value = [\n 'ingest.userAgent',\n 'event.user.userAgent',\n];\n\n/** A client IP or user agent setting resolved to a non-empty string. */\nasync function resolveClient(\n setting: WalkerOSMapping.Value | false | undefined,\n fallback: WalkerOSMapping.Value,\n root: WalkerOSMapping.Root,\n collector: Collector.Instance,\n): Promise<string | undefined> {\n if (setting === false) return undefined;\n const value = await getMappingValue(root, setting ?? fallback, { collector });\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n","import { WalkerOS } from '@walkeros/core';\nimport { isArray, isObject, isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\nconst keysToHash = [\n 'em',\n 'ph',\n 'fn',\n 'ln',\n 'db',\n 'ge',\n 'ct',\n 'st',\n 'zp',\n 'country',\n 'external_id',\n 'hashed_maids',\n];\n\nfunction shouldBeHashed(key: string, doNotHash: string[] = []): boolean {\n return keysToHash.includes(key) && !doNotHash.includes(key);\n}\n\ntype HashableValue = WalkerOS.AnyObject | unknown | unknown[];\n\nasync function processValue(\n value: unknown,\n shouldHash: boolean,\n): Promise<unknown> {\n if (!shouldHash) return value;\n if (isArray(value)) {\n return Promise.all(value.map((item) => getHashServer(String(item))));\n }\n return getHashServer(String(value));\n}\n\nexport async function hashEvent<T extends HashableValue>(\n value: T,\n doNotHash: string[] = [],\n): Promise<T> {\n if (!isObject(value)) return value;\n\n const isUserData = 'user_data' in value;\n const target = (isUserData ? value.user_data : value) as WalkerOS.AnyObject;\n\n const entries = await Promise.all(\n Object.entries(target).map(async ([k, v]) => [\n k,\n await processValue(v, isUserData && shouldBeHashed(k, doNotHash)),\n ]),\n );\n\n const result = entries.reduce((acc, [k, v]) => {\n if (isString(k)) acc[k] = v;\n return acc;\n }, {} as WalkerOS.AnyObject);\n\n return isUserData ? { ...value, user_data: result } : (result as T);\n}\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationServer, sendServer } from '@walkeros/server-core';\n\nexport interface Settings {\n accessToken: string;\n adAccountId: string;\n action_source?: ActionSource;\n doNotHash?: string[];\n test?: boolean;\n url?: string;\n user_data?: WalkerOSMapping.Map;\n partner_name?: string;\n /**\n * Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }.\n * `false` switches it off.\n * @default ['ingest.ip', 'event.user.ip']\n */\n ip?: WalkerOSMapping.Value | false;\n /**\n * Client user agent, sent as user_data.client_user_agent. Resolves against\n * { ingest, event }. `false` switches it off.\n * @default ['ingest.userAgent', 'event.user.userAgent']\n */\n userAgent?: WalkerOSMapping.Value | false;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// Pinterest Conversions API types\n// https://developers.pinterest.com/docs/conversions/conversions/\n\nexport type ActionSource = 'app_android' | 'app_ios' | 'web' | 'offline';\n\nexport type EventName =\n | 'add_payment_info'\n | 'add_to_cart'\n | 'add_to_wishlist'\n | 'app_install'\n | 'app_open'\n | 'checkout'\n | 'contact'\n | 'custom'\n | 'customize_product'\n | 'find_location'\n | 'initiate_checkout'\n | 'lead'\n | 'page_visit'\n | 'schedule'\n | 'search'\n | 'signup'\n | 'start_trial'\n | 'submit_application'\n | 'subscribe'\n | 'view_category'\n | 'view_content'\n | 'watch_video'\n | string;\n\nexport interface ConversionEvent {\n // Required\n event_name: EventName;\n event_time: number;\n event_id: string;\n action_source: ActionSource;\n user_data: UserData;\n\n // Optional\n event_source_url?: string;\n opt_out?: boolean;\n partner_name?: string;\n app_id?: string;\n app_name?: string;\n app_version?: string;\n device_brand?: string;\n device_carrier?: string;\n device_model?: string;\n device_type?: string;\n os_version?: string;\n language?: string;\n wifi?: boolean;\n custom_data?: CustomData;\n}\n\nexport interface UserData {\n // Hashable fields (SHA-256, arrays)\n em?: string[];\n ph?: string[];\n fn?: string[];\n ln?: string[];\n db?: string[];\n ge?: string[];\n ct?: string[];\n st?: string[];\n zp?: string[];\n country?: string[];\n external_id?: string[];\n hashed_maids?: string[];\n\n // Pass-through fields (do NOT hash)\n client_ip_address?: string;\n client_user_agent?: string;\n click_id?: string;\n partner_id?: string;\n}\n\nexport interface CustomData {\n currency?: string;\n value?: string;\n content_ids?: string[];\n content_name?: string;\n content_category?: string;\n content_brand?: string;\n contents?: ContentItem[];\n num_items?: number;\n order_id?: string;\n search_string?: string;\n opt_out_type?: string;\n np?: string;\n predicted_ltv?: string;\n}\n\nexport interface ContentItem {\n id?: string;\n item_name?: string;\n item_category?: string;\n item_brand?: string;\n item_price?: string;\n quantity?: number;\n}\n\nexport interface RequestBody {\n data: ConversionEvent[];\n}\n\nexport interface ResponseBody {\n num_events_received: number;\n num_events_processed: number;\n events: Array<{\n status: string;\n error_message?: string;\n warning_message?: string;\n }>;\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationPinterest from './types';\n\nexport const destinationPinterest: Destination = {\n type: 'pinterest',\n\n config: {},\n\n async init({ config: partialConfig, logger }) {\n const config = getConfig(partialConfig, logger);\n return config;\n },\n\n async push(event, context) {\n return await push(event, context);\n },\n};\n\nexport default destinationPinterest;\n"],"mappings":"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","names":["isObject","isObject"]}
|
package/dist/walkerOS.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$meta": {
|
|
3
3
|
"package": "@walkeros/server-destination-pinterest",
|
|
4
|
-
"version": "4.7.0
|
|
4
|
+
"version": "4.7.0",
|
|
5
5
|
"type": "destination",
|
|
6
6
|
"platform": [
|
|
7
7
|
"server"
|
|
8
8
|
],
|
|
9
|
+
"exports": {},
|
|
9
10
|
"docs": "https://www.walkeros.io/docs/destinations/server/pinterest-capi",
|
|
10
11
|
"source": "https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/pinterest/src"
|
|
11
12
|
},
|
|
@@ -69,13 +70,187 @@
|
|
|
69
70
|
"partner_name": {
|
|
70
71
|
"type": "string",
|
|
71
72
|
"description": "Third-party partner name for attribution (like ss-walkeros)"
|
|
73
|
+
},
|
|
74
|
+
"ip": {
|
|
75
|
+
"anyOf": [
|
|
76
|
+
{
|
|
77
|
+
"$ref": "#/definitions/MappingValue"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"type": "boolean",
|
|
81
|
+
"const": false
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
"description": "Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }. Default: [\"ingest.ip\", \"event.user.ip\"]. false switches it off. A mapped user_data.client_ip_address wins."
|
|
85
|
+
},
|
|
86
|
+
"userAgent": {
|
|
87
|
+
"anyOf": [
|
|
88
|
+
{
|
|
89
|
+
"$ref": "#/definitions/MappingValue"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"type": "boolean",
|
|
93
|
+
"const": false
|
|
94
|
+
}
|
|
95
|
+
],
|
|
96
|
+
"description": "Client user agent, sent as user_data.client_user_agent. Resolves against { ingest, event }. Default: [\"ingest.userAgent\", \"event.user.userAgent\"]. false switches it off. A mapped user_data.client_user_agent wins."
|
|
72
97
|
}
|
|
73
98
|
},
|
|
74
99
|
"required": [
|
|
75
100
|
"accessToken",
|
|
76
101
|
"adAccountId"
|
|
77
102
|
],
|
|
78
|
-
"additionalProperties": false
|
|
103
|
+
"additionalProperties": false,
|
|
104
|
+
"definitions": {
|
|
105
|
+
"MappingValue": {
|
|
106
|
+
"title": "Mapping.Value",
|
|
107
|
+
"description": "Polymorphic transform primitive used in every mapping field. A string path, constant, operator object (map/loop/set/condition/consent), or array of values.",
|
|
108
|
+
"anyOf": [
|
|
109
|
+
{
|
|
110
|
+
"type": "string",
|
|
111
|
+
"description": "String value or property path (e.g., \"data.id\")"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"type": "number",
|
|
115
|
+
"description": "Numeric value"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"type": "boolean",
|
|
119
|
+
"description": "Boolean value"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"description": "Value transformation configuration with multiple strategies",
|
|
123
|
+
"allOf": [
|
|
124
|
+
{
|
|
125
|
+
"$ref": "#/definitions/MappingValueConfig"
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"type": "array",
|
|
131
|
+
"items": {
|
|
132
|
+
"$ref": "#/definitions/MappingValue"
|
|
133
|
+
},
|
|
134
|
+
"description": "Array of values"
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
},
|
|
138
|
+
"MappingMap": {
|
|
139
|
+
"title": "Mapping.Map",
|
|
140
|
+
"description": "Map: object mapping keys to transformation values.",
|
|
141
|
+
"type": "object",
|
|
142
|
+
"propertyNames": {
|
|
143
|
+
"type": "string"
|
|
144
|
+
},
|
|
145
|
+
"additionalProperties": {
|
|
146
|
+
"$ref": "#/definitions/MappingValue"
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"MappingLoop": {
|
|
150
|
+
"title": "Mapping.Loop",
|
|
151
|
+
"description": "Loop tuple [source, transform] for iterating and transforming arrays.",
|
|
152
|
+
"minItems": 2,
|
|
153
|
+
"maxItems": 2,
|
|
154
|
+
"type": "array",
|
|
155
|
+
"items": [
|
|
156
|
+
{
|
|
157
|
+
"$ref": "#/definitions/MappingValue"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"$ref": "#/definitions/MappingValue"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
"MappingSet": {
|
|
165
|
+
"title": "Mapping.Set",
|
|
166
|
+
"description": "Set: array of values for selection or combination.",
|
|
167
|
+
"type": "array",
|
|
168
|
+
"items": {
|
|
169
|
+
"$ref": "#/definitions/MappingValue"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"WalkerOSConsent": {
|
|
173
|
+
"type": "object",
|
|
174
|
+
"propertyNames": {
|
|
175
|
+
"type": "string"
|
|
176
|
+
},
|
|
177
|
+
"additionalProperties": {
|
|
178
|
+
"type": "boolean"
|
|
179
|
+
},
|
|
180
|
+
"title": "WalkerOS.Consent",
|
|
181
|
+
"description": "Consent state mapping. Keys are consent groups (e.g. marketing, functional), values are booleans for granted/denied."
|
|
182
|
+
},
|
|
183
|
+
"MappingValueConfig": {
|
|
184
|
+
"type": "object",
|
|
185
|
+
"properties": {
|
|
186
|
+
"key": {
|
|
187
|
+
"description": "Property path to extract from event (e.g., \"data.id\", \"user.email\")",
|
|
188
|
+
"type": "string"
|
|
189
|
+
},
|
|
190
|
+
"value": {
|
|
191
|
+
"description": "Static primitive value",
|
|
192
|
+
"anyOf": [
|
|
193
|
+
{
|
|
194
|
+
"type": "string"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"type": "number"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"type": "boolean"
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
"fn": {
|
|
205
|
+
"description": "Custom transformation function as string (serialized)",
|
|
206
|
+
"type": "string"
|
|
207
|
+
},
|
|
208
|
+
"map": {
|
|
209
|
+
"description": "Object mapping: transform event data to structured output",
|
|
210
|
+
"allOf": [
|
|
211
|
+
{
|
|
212
|
+
"$ref": "#/definitions/MappingMap"
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
"loop": {
|
|
217
|
+
"description": "Loop transformation: [source, transform] for array processing",
|
|
218
|
+
"allOf": [
|
|
219
|
+
{
|
|
220
|
+
"$ref": "#/definitions/MappingLoop"
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
"set": {
|
|
225
|
+
"description": "Set of values: combine or select from multiple values",
|
|
226
|
+
"allOf": [
|
|
227
|
+
{
|
|
228
|
+
"$ref": "#/definitions/MappingSet"
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
},
|
|
232
|
+
"consent": {
|
|
233
|
+
"description": "Required consent states to include this value",
|
|
234
|
+
"allOf": [
|
|
235
|
+
{
|
|
236
|
+
"$ref": "#/definitions/WalkerOSConsent"
|
|
237
|
+
}
|
|
238
|
+
]
|
|
239
|
+
},
|
|
240
|
+
"condition": {
|
|
241
|
+
"description": "Condition function as string: return true to include value",
|
|
242
|
+
"type": "string"
|
|
243
|
+
},
|
|
244
|
+
"validate": {
|
|
245
|
+
"description": "Validation function as string: return true if value is valid",
|
|
246
|
+
"type": "string"
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
"additionalProperties": false,
|
|
250
|
+
"title": "Mapping.ValueConfig",
|
|
251
|
+
"description": "Object-form value transformation with map/loop/set/condition/consent etc."
|
|
252
|
+
}
|
|
253
|
+
}
|
|
79
254
|
}
|
|
80
255
|
},
|
|
81
256
|
"examples": {
|
|
@@ -253,7 +428,7 @@
|
|
|
253
428
|
"nested",
|
|
254
429
|
{
|
|
255
430
|
"condition": {
|
|
256
|
-
"$code": "e=>
|
|
431
|
+
"$code": "e=>y(e)&&\"product\"===e.entity"
|
|
257
432
|
},
|
|
258
433
|
"map": {
|
|
259
434
|
"id": "data.id",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/server-destination-pinterest",
|
|
3
3
|
"description": "Pinterest server destination for walkerOS",
|
|
4
|
-
"version": "4.7.0
|
|
4
|
+
"version": "4.7.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"update": "npx npm-check-updates -u && npm update"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@walkeros/core": "4.7.0
|
|
39
|
-
"@walkeros/server-core": "4.7.0
|
|
38
|
+
"@walkeros/core": "4.7.0",
|
|
39
|
+
"@walkeros/server-core": "4.7.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@walkeros/collector": "4.7.0
|
|
42
|
+
"@walkeros/collector": "4.7.0"
|
|
43
43
|
},
|
|
44
44
|
"repository": {
|
|
45
45
|
"url": "git+https://github.com/elbwalker/walkerOS.git",
|