@walkeros/server-destination-linkedin 3.4.1 → 4.0.0-next-1777463920154
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/examples/index.js +9 -6
- package/dist/examples/index.mjs +9 -6
- 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 +13 -41
- package/package.json +4 -4
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,t=Object.prototype.hasOwnProperty,o=(e,i)=>{for(var n in i)r(e,n,{get:i[n],enumerable:!0})},a={};o(a,{examples:()=>I,schemas:()=>s}),module.exports=(e=a,((e,o,a,s)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of n(o))t.call(e,c)||c===a||r(e,c,{get:()=>o[c],enumerable:!(s=i(o,c))||s.enumerable});return e})(r({},"__esModule",{value:!0}),e));var s={};o(s,{ApiVersionSchema:()=>p,MappingSchema:()=>f,SettingsSchema:()=>
|
|
1
|
+
"use strict";var e,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,t=Object.prototype.hasOwnProperty,o=(e,i)=>{for(var n in i)r(e,n,{get:i[n],enumerable:!0})},a={};o(a,{examples:()=>I,schemas:()=>s}),module.exports=(e=a,((e,o,a,s)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of n(o))t.call(e,c)||c===a||r(e,c,{get:()=>o[c],enumerable:!(s=i(o,c))||s.enumerable});return e})(r({},"__esModule",{value:!0}),e));var s={};o(s,{ApiVersionSchema:()=>p,MappingSchema:()=>f,SettingsSchema:()=>v,UserIdTypeSchema:()=>u,mapping:()=>h,settings:()=>b});var c=require("@walkeros/core/dev"),d=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),u=l.z.enum(["SHA256_EMAIL","LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID","ACXIOM_ID","ORACLE_MOAT_ID"]),p=l.z.string().regex(/^\d{6}$/,"API version must be in YYYYMM format (e.g. 202604)"),v=d.z.object({accessToken:d.z.string().min(1).describe("LinkedIn OAuth 2.0 Bearer token for Conversions API authentication (like AQX...)"),conversionRuleId:d.z.string().regex(/^[0-9]+$/,"Conversion rule ID must contain only digits").describe("Default LinkedIn conversion rule ID from Campaign Manager (like 12345678)"),apiVersion:p.describe("Linkedin-Version header value in YYYYMM format (like 202604)").optional(),doNotHash:d.z.array(d.z.string()).describe("Array of user data fields that should not be hashed (like ['email'])").optional(),url:d.z.string().url().describe("Custom URL for LinkedIn Conversions API endpoint (like https://api.linkedin.com/rest/)").optional(),user_data:d.z.record(d.z.string(),d.z.string()).describe("Mapping configuration for user data fields (like { email: 'user.email', li_fat_id: 'context.li_fat_id' })").optional()}),m=require("@walkeros/core/dev"),f=m.z.object({conversion:m.z.object({ruleId:m.z.string().describe("Override conversion rule ID for this event").optional(),value:m.z.union([m.z.string(),m.z.number()]).describe("Conversion monetary value").optional(),currency:m.z.string().describe("ISO 4217 currency code (like USD, EUR)").optional()}).describe("Per-event conversion override with ruleId, value, and currency").optional()}),b=(0,c.zodToSchema)(v),h=(0,c.zodToSchema)(f),I={};o(I,{env:()=>y,step:()=>A});var y={};o(y,{push:()=>g,simulation:()=>_});var g={sendServer:async function(e,r,i){return{ok:!0,data:{}}}},_=["sendServer"],A={};o(A,{lead:()=>L,purchase:()=>C,purchaseWithLiFatId:()=>T});var S=require("@walkeros/core"),k="https://api.linkedin.com/rest/conversionEvents",z={headers:{Authorization:"Bearer s3cr3t","Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0","X-RestLi-Method":"BATCH_CREATE","Linkedin-Version":"202604"}},C={title:"Purchase",description:"A completed order is sent to the LinkedIn Conversions API with conversion value, currency, and hashed email.",in:(0,S.getEvent)("order complete",{id:"ev-1700000900000",timestamp:17000009e5,data:{total:249.99,currency:"EUR"},user:{email:"jane@example.com"},source:{type:"express",platform:"server"}}),mapping:{settings:{conversion:{map:{value:"data.total",currency:{key:"data.currency",value:"EUR"}}}}},out:[["sendServer",k,JSON.stringify({elements:[{conversion:"urn:lla:llaPartnerConversion:12345678",conversionHappenedAt:17000009e5,user:{userIds:[{idType:"SHA256_EMAIL",idValue:"8c87b489ce35cf2e2f39f80e282cb2e804932a56a213983eeeb428407d43b52d"}]},eventId:"ev-1700000900000",conversionValue:{currencyCode:"EUR",amount:"249.99"}}]}),z]]},L={title:"Lead",description:"A form submission is posted to LinkedIn as a conversion with the SHA-256 hashed email as the user identifier.",in:(0,S.getEvent)("form submit",{id:"ev-1700000901000",timestamp:1700000901e3,user:{email:"user@example.com"},source:{type:"express",platform:"server"}}),mapping:void 0,out:[["sendServer",k,JSON.stringify({elements:[{conversion:"urn:lla:llaPartnerConversion:12345678",conversionHappenedAt:1700000901e3,user:{userIds:[{idType:"SHA256_EMAIL",idValue:"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514"}]},eventId:"ev-1700000901000"}]}),z]]},T={title:"Purchase with li_fat_id",description:"A purchase is sent to LinkedIn with both the hashed email and the first-party li_fat_id tracking identifier.",in:(0,S.getEvent)("order complete",{id:"ev-1700000902000",timestamp:1700000902e3,data:{total:89.99,currency:"USD"},user:{email:"buyer@co.com"},context:{li_fat_id:["abc123-fat-id",0]},source:{type:"express",platform:"server"}}),mapping:{settings:{conversion:{map:{value:"data.total",currency:{key:"data.currency",value:"USD"}}}},data:{map:{user_data:{map:{li_fat_id:"context.li_fat_id"}}}}},out:[["sendServer",k,JSON.stringify({elements:[{conversion:"urn:lla:llaPartnerConversion:12345678",conversionHappenedAt:1700000902e3,user:{userIds:[{idType:"SHA256_EMAIL",idValue:"484c39bfb51212665d9673805c112b5ba04cbf0460b6d3f00bcdc18b92afed66"},{idType:"LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID",idValue:"abc123-fat-id"}]},eventId:"ev-1700000902000",conversionValue:{currencyCode:"USD",amount:"89.99"}}]}),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 { ApiVersionSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'LinkedIn OAuth 2.0 Bearer token for Conversions API authentication (like AQX...)',\n ),\n conversionRuleId: z\n .string()\n .regex(/^[0-9]+$/, 'Conversion rule ID must contain only digits')\n .describe(\n 'Default LinkedIn conversion rule ID from Campaign Manager (like 12345678)',\n ),\n apiVersion: ApiVersionSchema.describe(\n 'Linkedin-Version header value in YYYYMM format (like 202604)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\n \"Array of user data fields that should not be hashed (like ['email'])\",\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for LinkedIn Conversions API endpoint (like https://api.linkedin.com/rest/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user data fields (like { email: 'user.email', li_fat_id: 'context.li_fat_id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * LinkedIn User ID Type Enum\n * Types of user identifiers supported by LinkedIn Conversions API\n */\nexport const UserIdTypeSchema = z.enum([\n 'SHA256_EMAIL',\n 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n 'ACXIOM_ID',\n 'ORACLE_MOAT_ID',\n]);\n\n/**\n * API Version Schema\n * LinkedIn-Version header value in YYYYMM format\n */\nexport const ApiVersionSchema = z\n .string()\n .regex(/^\\d{6}$/, 'API version must be in YYYYMM format (e.g. 202604)');\n","import { z } from '@walkeros/core/dev';\n\n/**\n * LinkedIn Conversions API Mapping Schema\n *\n * Per-event override for conversion rule, value, and currency.\n * The `conversion` field is a mapping value that resolves to an object\n * with optional `ruleId`, `value`, and `currency` keys.\n */\nexport const MappingSchema = z.object({\n conversion: z\n .object({\n ruleId: z\n .string()\n .describe('Override conversion rule ID for this event')\n .optional(),\n value: z\n .union([z.string(), z.number()])\n .describe('Conversion monetary value')\n .optional(),\n currency: z\n .string()\n .describe('ISO 4217 currency code (like USD, EUR)')\n .optional(),\n })\n .describe('Per-event conversion override with ruleId, value, and currency')\n .optional(),\n});\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 LinkedIn 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 return {\n ok: true,\n data: {},\n };\n}\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing LinkedIn Conversions API events without making\n * actual HTTP requests to LinkedIn's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\n\n/**\n * LinkedIn Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * endpoint = `${settings.url}conversionEvents`\n * body = `{ elements: [conversionEvent] }`\n *\n * Test fixture pins `conversionRuleId = '12345678'` and the default url, so\n * every call targets:\n * https://api.linkedin.com/rest/conversionEvents\n *\n * Each conversion event is emitted with keys in the destination's build order:\n * 1. conversion (`urn:lla:llaPartnerConversion:<ruleId>`)\n * 2. conversionHappenedAt (raw `event.timestamp` in ms)\n * 3. user\n * 4. eventId\n * 5. conversionValue (only when mapping provides a value)\n *\n * `options` carries the Authorization + LinkedIn-specific headers.\n */\nconst ENDPOINT = 'https://api.linkedin.com/rest/conversionEvents';\nconst OPTIONS = {\n headers: {\n Authorization: 'Bearer s3cr3t',\n 'Content-Type': 'application/json',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n 'Linkedin-Version': '202604',\n },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the LinkedIn Conversions API with conversion value, currency, and hashed email.',\n in: getEvent('order complete', {\n timestamp: 1700000900000,\n data: { total: 249.99, currency: 'EUR' },\n user: { email: 'jane@example.com' },\n source: { type: 'server', id: 'https://shop.example.com', previous_id: '' },\n }),\n mapping: {\n settings: {\n conversion: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000900000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('jane@example.com')\n idValue:\n '8c87b489ce35cf2e2f39f80e282cb2e804932a56a213983eeeb428407d43b52d',\n },\n ],\n },\n eventId: '1700000900000-gr0up-1',\n conversionValue: {\n currencyCode: 'EUR',\n amount: '249.99',\n },\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A form submission is posted to LinkedIn as a conversion with the SHA-256 hashed email as the user identifier.',\n in: getEvent('form submit', {\n timestamp: 1700000901000,\n user: { email: 'user@example.com' },\n source: { type: 'server', id: 'https://example.com', previous_id: '' },\n }),\n mapping: undefined,\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000901000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('user@example.com')\n idValue:\n 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514',\n },\n ],\n },\n eventId: '1700000901000-gr0up-1',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const purchaseWithLiFatId: Flow.StepExample = {\n title: 'Purchase with li_fat_id',\n description:\n 'A purchase is sent to LinkedIn with both the hashed email and the first-party li_fat_id tracking identifier.',\n in: getEvent('order complete', {\n timestamp: 1700000902000,\n data: { total: 89.99, currency: 'USD' },\n user: { email: 'buyer@co.com' },\n context: { li_fat_id: ['abc123-fat-id', 0] },\n source: { type: 'server', id: 'https://shop.example.com', previous_id: '' },\n }),\n mapping: {\n settings: {\n conversion: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'USD' },\n },\n },\n },\n data: {\n map: {\n user_data: {\n map: {\n li_fat_id: 'context.li_fat_id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000902000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('buyer@co.com')\n idValue:\n '484c39bfb51212665d9673805c112b5ba04cbf0460b6d3f00bcdc18b92afed66',\n },\n {\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: 'abc123-fat-id',\n },\n ],\n },\n eventId: '1700000902000-gr0up-1',\n conversionValue: {\n currencyCode: 'USD',\n amount: '89.99',\n },\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 { z } from '@walkeros/core/dev';\nimport { ApiVersionSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'LinkedIn OAuth 2.0 Bearer token for Conversions API authentication (like AQX...)',\n ),\n conversionRuleId: z\n .string()\n .regex(/^[0-9]+$/, 'Conversion rule ID must contain only digits')\n .describe(\n 'Default LinkedIn conversion rule ID from Campaign Manager (like 12345678)',\n ),\n apiVersion: ApiVersionSchema.describe(\n 'Linkedin-Version header value in YYYYMM format (like 202604)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\n \"Array of user data fields that should not be hashed (like ['email'])\",\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for LinkedIn Conversions API endpoint (like https://api.linkedin.com/rest/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user data fields (like { email: 'user.email', li_fat_id: 'context.li_fat_id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * LinkedIn User ID Type Enum\n * Types of user identifiers supported by LinkedIn Conversions API\n */\nexport const UserIdTypeSchema = z.enum([\n 'SHA256_EMAIL',\n 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n 'ACXIOM_ID',\n 'ORACLE_MOAT_ID',\n]);\n\n/**\n * API Version Schema\n * LinkedIn-Version header value in YYYYMM format\n */\nexport const ApiVersionSchema = z\n .string()\n .regex(/^\\d{6}$/, 'API version must be in YYYYMM format (e.g. 202604)');\n","import { z } from '@walkeros/core/dev';\n\n/**\n * LinkedIn Conversions API Mapping Schema\n *\n * Per-event override for conversion rule, value, and currency.\n * The `conversion` field is a mapping value that resolves to an object\n * with optional `ruleId`, `value`, and `currency` keys.\n */\nexport const MappingSchema = z.object({\n conversion: z\n .object({\n ruleId: z\n .string()\n .describe('Override conversion rule ID for this event')\n .optional(),\n value: z\n .union([z.string(), z.number()])\n .describe('Conversion monetary value')\n .optional(),\n currency: z\n .string()\n .describe('ISO 4217 currency code (like USD, EUR)')\n .optional(),\n })\n .describe('Per-event conversion override with ruleId, value, and currency')\n .optional(),\n});\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 LinkedIn 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 return {\n ok: true,\n data: {},\n };\n}\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing LinkedIn Conversions API events without making\n * actual HTTP requests to LinkedIn's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\n\n/**\n * LinkedIn Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * endpoint = `${settings.url}conversionEvents`\n * body = `{ elements: [conversionEvent] }`\n *\n * Test fixture pins `conversionRuleId = '12345678'` and the default url, so\n * every call targets:\n * https://api.linkedin.com/rest/conversionEvents\n *\n * Each conversion event is emitted with keys in the destination's build order:\n * 1. conversion (`urn:lla:llaPartnerConversion:<ruleId>`)\n * 2. conversionHappenedAt (raw `event.timestamp` in ms)\n * 3. user\n * 4. eventId\n * 5. conversionValue (only when mapping provides a value)\n *\n * `options` carries the Authorization + LinkedIn-specific headers.\n */\nconst ENDPOINT = 'https://api.linkedin.com/rest/conversionEvents';\nconst OPTIONS = {\n headers: {\n Authorization: 'Bearer s3cr3t',\n 'Content-Type': 'application/json',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n 'Linkedin-Version': '202604',\n },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the LinkedIn Conversions API with conversion value, currency, and hashed email.',\n in: getEvent('order complete', {\n id: 'ev-1700000900000',\n timestamp: 1700000900000,\n data: { total: 249.99, currency: 'EUR' },\n user: { email: 'jane@example.com' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n settings: {\n conversion: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000900000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('jane@example.com')\n idValue:\n '8c87b489ce35cf2e2f39f80e282cb2e804932a56a213983eeeb428407d43b52d',\n },\n ],\n },\n eventId: 'ev-1700000900000',\n conversionValue: {\n currencyCode: 'EUR',\n amount: '249.99',\n },\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A form submission is posted to LinkedIn as a conversion with the SHA-256 hashed email as the user identifier.',\n in: getEvent('form submit', {\n id: 'ev-1700000901000',\n timestamp: 1700000901000,\n user: { email: 'user@example.com' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: undefined,\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000901000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('user@example.com')\n idValue:\n 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514',\n },\n ],\n },\n eventId: 'ev-1700000901000',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const purchaseWithLiFatId: Flow.StepExample = {\n title: 'Purchase with li_fat_id',\n description:\n 'A purchase is sent to LinkedIn with both the hashed email and the first-party li_fat_id tracking identifier.',\n in: getEvent('order complete', {\n id: 'ev-1700000902000',\n timestamp: 1700000902000,\n data: { total: 89.99, currency: 'USD' },\n user: { email: 'buyer@co.com' },\n context: { li_fat_id: ['abc123-fat-id', 0] },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n settings: {\n conversion: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'USD' },\n },\n },\n },\n data: {\n map: {\n user_data: {\n map: {\n li_fat_id: 'context.li_fat_id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000902000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('buyer@co.com')\n idValue:\n '484c39bfb51212665d9673805c112b5ba04cbf0460b6d3f00bcdc18b92afed66',\n },\n {\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: 'abc123-fat-id',\n },\n ],\n },\n eventId: 'ev-1700000902000',\n conversionValue: {\n currencyCode: 'USD',\n amount: '89.99',\n },\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["import_dev","import_dev","import_dev"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,r=(r,i)=>{for(var n in i)e(r,n,{get:i[n],enumerable:!0})},i={};r(i,{ApiVersionSchema:()=>s,MappingSchema:()=>l,SettingsSchema:()=>c,UserIdTypeSchema:()=>
|
|
1
|
+
var e=Object.defineProperty,r=(r,i)=>{for(var n in i)e(r,n,{get:i[n],enumerable:!0})},i={};r(i,{ApiVersionSchema:()=>s,MappingSchema:()=>l,SettingsSchema:()=>c,UserIdTypeSchema:()=>o,mapping:()=>p,settings:()=>u});import{zodToSchema as n}from"@walkeros/core/dev";import{z as t}from"@walkeros/core/dev";import{z as a}from"@walkeros/core/dev";var o=a.enum(["SHA256_EMAIL","LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID","ACXIOM_ID","ORACLE_MOAT_ID"]),s=a.string().regex(/^\d{6}$/,"API version must be in YYYYMM format (e.g. 202604)"),c=t.object({accessToken:t.string().min(1).describe("LinkedIn OAuth 2.0 Bearer token for Conversions API authentication (like AQX...)"),conversionRuleId:t.string().regex(/^[0-9]+$/,"Conversion rule ID must contain only digits").describe("Default LinkedIn conversion rule ID from Campaign Manager (like 12345678)"),apiVersion:s.describe("Linkedin-Version header value in YYYYMM format (like 202604)").optional(),doNotHash:t.array(t.string()).describe("Array of user data fields that should not be hashed (like ['email'])").optional(),url:t.string().url().describe("Custom URL for LinkedIn Conversions API endpoint (like https://api.linkedin.com/rest/)").optional(),user_data:t.record(t.string(),t.string()).describe("Mapping configuration for user data fields (like { email: 'user.email', li_fat_id: 'context.li_fat_id' })").optional()});import{z as d}from"@walkeros/core/dev";var l=d.object({conversion:d.object({ruleId:d.string().describe("Override conversion rule ID for this event").optional(),value:d.union([d.string(),d.number()]).describe("Conversion monetary value").optional(),currency:d.string().describe("ISO 4217 currency code (like USD, EUR)").optional()}).describe("Per-event conversion override with ruleId, value, and currency").optional()}),u=n(c),p=n(l),m={};r(m,{env:()=>v,step:()=>I});var v={};r(v,{push:()=>f,simulation:()=>h});var f={sendServer:async function(e,r,i){return{ok:!0,data:{}}}},h=["sendServer"],I={};r(I,{lead:()=>g,purchase:()=>_,purchaseWithLiFatId:()=>k});import{getEvent as b}from"@walkeros/core";var A="https://api.linkedin.com/rest/conversionEvents",y={headers:{Authorization:"Bearer s3cr3t","Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0","X-RestLi-Method":"BATCH_CREATE","Linkedin-Version":"202604"}},_={title:"Purchase",description:"A completed order is sent to the LinkedIn Conversions API with conversion value, currency, and hashed email.",in:b("order complete",{id:"ev-1700000900000",timestamp:17000009e5,data:{total:249.99,currency:"EUR"},user:{email:"jane@example.com"},source:{type:"express",platform:"server"}}),mapping:{settings:{conversion:{map:{value:"data.total",currency:{key:"data.currency",value:"EUR"}}}}},out:[["sendServer",A,JSON.stringify({elements:[{conversion:"urn:lla:llaPartnerConversion:12345678",conversionHappenedAt:17000009e5,user:{userIds:[{idType:"SHA256_EMAIL",idValue:"8c87b489ce35cf2e2f39f80e282cb2e804932a56a213983eeeb428407d43b52d"}]},eventId:"ev-1700000900000",conversionValue:{currencyCode:"EUR",amount:"249.99"}}]}),y]]},g={title:"Lead",description:"A form submission is posted to LinkedIn as a conversion with the SHA-256 hashed email as the user identifier.",in:b("form submit",{id:"ev-1700000901000",timestamp:1700000901e3,user:{email:"user@example.com"},source:{type:"express",platform:"server"}}),mapping:void 0,out:[["sendServer",A,JSON.stringify({elements:[{conversion:"urn:lla:llaPartnerConversion:12345678",conversionHappenedAt:1700000901e3,user:{userIds:[{idType:"SHA256_EMAIL",idValue:"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514"}]},eventId:"ev-1700000901000"}]}),y]]},k={title:"Purchase with li_fat_id",description:"A purchase is sent to LinkedIn with both the hashed email and the first-party li_fat_id tracking identifier.",in:b("order complete",{id:"ev-1700000902000",timestamp:1700000902e3,data:{total:89.99,currency:"USD"},user:{email:"buyer@co.com"},context:{li_fat_id:["abc123-fat-id",0]},source:{type:"express",platform:"server"}}),mapping:{settings:{conversion:{map:{value:"data.total",currency:{key:"data.currency",value:"USD"}}}},data:{map:{user_data:{map:{li_fat_id:"context.li_fat_id"}}}}},out:[["sendServer",A,JSON.stringify({elements:[{conversion:"urn:lla:llaPartnerConversion:12345678",conversionHappenedAt:1700000902e3,user:{userIds:[{idType:"SHA256_EMAIL",idValue:"484c39bfb51212665d9673805c112b5ba04cbf0460b6d3f00bcdc18b92afed66"},{idType:"LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID",idValue:"abc123-fat-id"}]},eventId:"ev-1700000902000",conversionValue:{currencyCode:"USD",amount:"89.99"}}]}),y]]};export{m as examples,i as schemas};//# sourceMappingURL=dev.mjs.map
|
package/dist/dev.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/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 { ApiVersionSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'LinkedIn OAuth 2.0 Bearer token for Conversions API authentication (like AQX...)',\n ),\n conversionRuleId: z\n .string()\n .regex(/^[0-9]+$/, 'Conversion rule ID must contain only digits')\n .describe(\n 'Default LinkedIn conversion rule ID from Campaign Manager (like 12345678)',\n ),\n apiVersion: ApiVersionSchema.describe(\n 'Linkedin-Version header value in YYYYMM format (like 202604)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\n \"Array of user data fields that should not be hashed (like ['email'])\",\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for LinkedIn Conversions API endpoint (like https://api.linkedin.com/rest/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user data fields (like { email: 'user.email', li_fat_id: 'context.li_fat_id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * LinkedIn User ID Type Enum\n * Types of user identifiers supported by LinkedIn Conversions API\n */\nexport const UserIdTypeSchema = z.enum([\n 'SHA256_EMAIL',\n 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n 'ACXIOM_ID',\n 'ORACLE_MOAT_ID',\n]);\n\n/**\n * API Version Schema\n * LinkedIn-Version header value in YYYYMM format\n */\nexport const ApiVersionSchema = z\n .string()\n .regex(/^\\d{6}$/, 'API version must be in YYYYMM format (e.g. 202604)');\n","import { z } from '@walkeros/core/dev';\n\n/**\n * LinkedIn Conversions API Mapping Schema\n *\n * Per-event override for conversion rule, value, and currency.\n * The `conversion` field is a mapping value that resolves to an object\n * with optional `ruleId`, `value`, and `currency` keys.\n */\nexport const MappingSchema = z.object({\n conversion: z\n .object({\n ruleId: z\n .string()\n .describe('Override conversion rule ID for this event')\n .optional(),\n value: z\n .union([z.string(), z.number()])\n .describe('Conversion monetary value')\n .optional(),\n currency: z\n .string()\n .describe('ISO 4217 currency code (like USD, EUR)')\n .optional(),\n })\n .describe('Per-event conversion override with ruleId, value, and currency')\n .optional(),\n});\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 LinkedIn 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 return {\n ok: true,\n data: {},\n };\n}\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing LinkedIn Conversions API events without making\n * actual HTTP requests to LinkedIn's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\n\n/**\n * LinkedIn Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * endpoint = `${settings.url}conversionEvents`\n * body = `{ elements: [conversionEvent] }`\n *\n * Test fixture pins `conversionRuleId = '12345678'` and the default url, so\n * every call targets:\n * https://api.linkedin.com/rest/conversionEvents\n *\n * Each conversion event is emitted with keys in the destination's build order:\n * 1. conversion (`urn:lla:llaPartnerConversion:<ruleId>`)\n * 2. conversionHappenedAt (raw `event.timestamp` in ms)\n * 3. user\n * 4. eventId\n * 5. conversionValue (only when mapping provides a value)\n *\n * `options` carries the Authorization + LinkedIn-specific headers.\n */\nconst ENDPOINT = 'https://api.linkedin.com/rest/conversionEvents';\nconst OPTIONS = {\n headers: {\n Authorization: 'Bearer s3cr3t',\n 'Content-Type': 'application/json',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n 'Linkedin-Version': '202604',\n },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the LinkedIn Conversions API with conversion value, currency, and hashed email.',\n in: getEvent('order complete', {\n timestamp: 1700000900000,\n data: { total: 249.99, currency: 'EUR' },\n user: { email: 'jane@example.com' },\n source: { type: 'server', id: 'https://shop.example.com', previous_id: '' },\n }),\n mapping: {\n settings: {\n conversion: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000900000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('jane@example.com')\n idValue:\n '8c87b489ce35cf2e2f39f80e282cb2e804932a56a213983eeeb428407d43b52d',\n },\n ],\n },\n eventId: '1700000900000-gr0up-1',\n conversionValue: {\n currencyCode: 'EUR',\n amount: '249.99',\n },\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A form submission is posted to LinkedIn as a conversion with the SHA-256 hashed email as the user identifier.',\n in: getEvent('form submit', {\n timestamp: 1700000901000,\n user: { email: 'user@example.com' },\n source: { type: 'server', id: 'https://example.com', previous_id: '' },\n }),\n mapping: undefined,\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000901000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('user@example.com')\n idValue:\n 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514',\n },\n ],\n },\n eventId: '1700000901000-gr0up-1',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const purchaseWithLiFatId: Flow.StepExample = {\n title: 'Purchase with li_fat_id',\n description:\n 'A purchase is sent to LinkedIn with both the hashed email and the first-party li_fat_id tracking identifier.',\n in: getEvent('order complete', {\n timestamp: 1700000902000,\n data: { total: 89.99, currency: 'USD' },\n user: { email: 'buyer@co.com' },\n context: { li_fat_id: ['abc123-fat-id', 0] },\n source: { type: 'server', id: 'https://shop.example.com', previous_id: '' },\n }),\n mapping: {\n settings: {\n conversion: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'USD' },\n },\n },\n },\n data: {\n map: {\n user_data: {\n map: {\n li_fat_id: 'context.li_fat_id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000902000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('buyer@co.com')\n idValue:\n '484c39bfb51212665d9673805c112b5ba04cbf0460b6d3f00bcdc18b92afed66',\n },\n {\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: 'abc123-fat-id',\n },\n ],\n },\n eventId: '1700000902000-gr0up-1',\n conversionValue: {\n currencyCode: 'USD',\n amount: '89.99',\n },\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 { z } from '@walkeros/core/dev';\nimport { ApiVersionSchema } from './primitives';\n\nexport const SettingsSchema = z.object({\n accessToken: z\n .string()\n .min(1)\n .describe(\n 'LinkedIn OAuth 2.0 Bearer token for Conversions API authentication (like AQX...)',\n ),\n conversionRuleId: z\n .string()\n .regex(/^[0-9]+$/, 'Conversion rule ID must contain only digits')\n .describe(\n 'Default LinkedIn conversion rule ID from Campaign Manager (like 12345678)',\n ),\n apiVersion: ApiVersionSchema.describe(\n 'Linkedin-Version header value in YYYYMM format (like 202604)',\n ).optional(),\n doNotHash: z\n .array(z.string())\n .describe(\n \"Array of user data fields that should not be hashed (like ['email'])\",\n )\n .optional(),\n url: z\n .string()\n .url()\n .describe(\n 'Custom URL for LinkedIn Conversions API endpoint (like https://api.linkedin.com/rest/)',\n )\n .optional(),\n user_data: z\n .record(z.string(), z.string())\n .describe(\n \"Mapping configuration for user data fields (like { email: 'user.email', li_fat_id: 'context.li_fat_id' })\",\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * LinkedIn User ID Type Enum\n * Types of user identifiers supported by LinkedIn Conversions API\n */\nexport const UserIdTypeSchema = z.enum([\n 'SHA256_EMAIL',\n 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n 'ACXIOM_ID',\n 'ORACLE_MOAT_ID',\n]);\n\n/**\n * API Version Schema\n * LinkedIn-Version header value in YYYYMM format\n */\nexport const ApiVersionSchema = z\n .string()\n .regex(/^\\d{6}$/, 'API version must be in YYYYMM format (e.g. 202604)');\n","import { z } from '@walkeros/core/dev';\n\n/**\n * LinkedIn Conversions API Mapping Schema\n *\n * Per-event override for conversion rule, value, and currency.\n * The `conversion` field is a mapping value that resolves to an object\n * with optional `ruleId`, `value`, and `currency` keys.\n */\nexport const MappingSchema = z.object({\n conversion: z\n .object({\n ruleId: z\n .string()\n .describe('Override conversion rule ID for this event')\n .optional(),\n value: z\n .union([z.string(), z.number()])\n .describe('Conversion monetary value')\n .optional(),\n currency: z\n .string()\n .describe('ISO 4217 currency code (like USD, EUR)')\n .optional(),\n })\n .describe('Per-event conversion override with ruleId, value, and currency')\n .optional(),\n});\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 LinkedIn 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 return {\n ok: true,\n data: {},\n };\n}\n\n/**\n * Standard mock environment for push operations\n *\n * Use this for testing LinkedIn Conversions API events without making\n * actual HTTP requests to LinkedIn's servers.\n */\nexport const push: Env = {\n sendServer: mockSendServer,\n};\n\nexport const simulation = ['sendServer'];\n","import type { Flow } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\n\n/**\n * LinkedIn Conversions API step examples.\n *\n * At push time, the destination calls\n * `env.sendServer(endpoint, JSON.stringify(body), options)` where\n * endpoint = `${settings.url}conversionEvents`\n * body = `{ elements: [conversionEvent] }`\n *\n * Test fixture pins `conversionRuleId = '12345678'` and the default url, so\n * every call targets:\n * https://api.linkedin.com/rest/conversionEvents\n *\n * Each conversion event is emitted with keys in the destination's build order:\n * 1. conversion (`urn:lla:llaPartnerConversion:<ruleId>`)\n * 2. conversionHappenedAt (raw `event.timestamp` in ms)\n * 3. user\n * 4. eventId\n * 5. conversionValue (only when mapping provides a value)\n *\n * `options` carries the Authorization + LinkedIn-specific headers.\n */\nconst ENDPOINT = 'https://api.linkedin.com/rest/conversionEvents';\nconst OPTIONS = {\n headers: {\n Authorization: 'Bearer s3cr3t',\n 'Content-Type': 'application/json',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n 'Linkedin-Version': '202604',\n },\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase',\n description:\n 'A completed order is sent to the LinkedIn Conversions API with conversion value, currency, and hashed email.',\n in: getEvent('order complete', {\n id: 'ev-1700000900000',\n timestamp: 1700000900000,\n data: { total: 249.99, currency: 'EUR' },\n user: { email: 'jane@example.com' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n settings: {\n conversion: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000900000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('jane@example.com')\n idValue:\n '8c87b489ce35cf2e2f39f80e282cb2e804932a56a213983eeeb428407d43b52d',\n },\n ],\n },\n eventId: 'ev-1700000900000',\n conversionValue: {\n currencyCode: 'EUR',\n amount: '249.99',\n },\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const lead: Flow.StepExample = {\n title: 'Lead',\n description:\n 'A form submission is posted to LinkedIn as a conversion with the SHA-256 hashed email as the user identifier.',\n in: getEvent('form submit', {\n id: 'ev-1700000901000',\n timestamp: 1700000901000,\n user: { email: 'user@example.com' },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: undefined,\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000901000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('user@example.com')\n idValue:\n 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514',\n },\n ],\n },\n eventId: 'ev-1700000901000',\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n\nexport const purchaseWithLiFatId: Flow.StepExample = {\n title: 'Purchase with li_fat_id',\n description:\n 'A purchase is sent to LinkedIn with both the hashed email and the first-party li_fat_id tracking identifier.',\n in: getEvent('order complete', {\n id: 'ev-1700000902000',\n timestamp: 1700000902000,\n data: { total: 89.99, currency: 'USD' },\n user: { email: 'buyer@co.com' },\n context: { li_fat_id: ['abc123-fat-id', 0] },\n source: { type: 'express', platform: 'server' },\n }),\n mapping: {\n settings: {\n conversion: {\n map: {\n value: 'data.total',\n currency: { key: 'data.currency', value: 'USD' },\n },\n },\n },\n data: {\n map: {\n user_data: {\n map: {\n li_fat_id: 'context.li_fat_id',\n },\n },\n },\n },\n },\n out: [\n [\n 'sendServer',\n ENDPOINT,\n JSON.stringify({\n elements: [\n {\n conversion: 'urn:lla:llaPartnerConversion:12345678',\n conversionHappenedAt: 1700000902000,\n user: {\n userIds: [\n {\n idType: 'SHA256_EMAIL',\n // sha256('buyer@co.com')\n idValue:\n '484c39bfb51212665d9673805c112b5ba04cbf0460b6d3f00bcdc18b92afed66',\n },\n {\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: 'abc123-fat-id',\n },\n ],\n },\n eventId: 'ev-1700000902000',\n conversionValue: {\n currencyCode: 'USD',\n amount: '89.99',\n },\n },\n ],\n }),\n OPTIONS,\n ],\n ],\n};\n"],"mappings":"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","names":["z","z","z"]}
|
package/dist/examples/index.js
CHANGED
|
@@ -64,10 +64,11 @@ var purchase = {
|
|
|
64
64
|
title: "Purchase",
|
|
65
65
|
description: "A completed order is sent to the LinkedIn Conversions API with conversion value, currency, and hashed email.",
|
|
66
66
|
in: (0, import_core.getEvent)("order complete", {
|
|
67
|
+
id: "ev-1700000900000",
|
|
67
68
|
timestamp: 17000009e5,
|
|
68
69
|
data: { total: 249.99, currency: "EUR" },
|
|
69
70
|
user: { email: "jane@example.com" },
|
|
70
|
-
source: { type: "
|
|
71
|
+
source: { type: "express", platform: "server" }
|
|
71
72
|
}),
|
|
72
73
|
mapping: {
|
|
73
74
|
settings: {
|
|
@@ -97,7 +98,7 @@ var purchase = {
|
|
|
97
98
|
}
|
|
98
99
|
]
|
|
99
100
|
},
|
|
100
|
-
eventId: "1700000900000
|
|
101
|
+
eventId: "ev-1700000900000",
|
|
101
102
|
conversionValue: {
|
|
102
103
|
currencyCode: "EUR",
|
|
103
104
|
amount: "249.99"
|
|
@@ -113,9 +114,10 @@ var lead = {
|
|
|
113
114
|
title: "Lead",
|
|
114
115
|
description: "A form submission is posted to LinkedIn as a conversion with the SHA-256 hashed email as the user identifier.",
|
|
115
116
|
in: (0, import_core.getEvent)("form submit", {
|
|
117
|
+
id: "ev-1700000901000",
|
|
116
118
|
timestamp: 1700000901e3,
|
|
117
119
|
user: { email: "user@example.com" },
|
|
118
|
-
source: { type: "
|
|
120
|
+
source: { type: "express", platform: "server" }
|
|
119
121
|
}),
|
|
120
122
|
mapping: void 0,
|
|
121
123
|
out: [
|
|
@@ -136,7 +138,7 @@ var lead = {
|
|
|
136
138
|
}
|
|
137
139
|
]
|
|
138
140
|
},
|
|
139
|
-
eventId: "1700000901000
|
|
141
|
+
eventId: "ev-1700000901000"
|
|
140
142
|
}
|
|
141
143
|
]
|
|
142
144
|
}),
|
|
@@ -148,11 +150,12 @@ var purchaseWithLiFatId = {
|
|
|
148
150
|
title: "Purchase with li_fat_id",
|
|
149
151
|
description: "A purchase is sent to LinkedIn with both the hashed email and the first-party li_fat_id tracking identifier.",
|
|
150
152
|
in: (0, import_core.getEvent)("order complete", {
|
|
153
|
+
id: "ev-1700000902000",
|
|
151
154
|
timestamp: 1700000902e3,
|
|
152
155
|
data: { total: 89.99, currency: "USD" },
|
|
153
156
|
user: { email: "buyer@co.com" },
|
|
154
157
|
context: { li_fat_id: ["abc123-fat-id", 0] },
|
|
155
|
-
source: { type: "
|
|
158
|
+
source: { type: "express", platform: "server" }
|
|
156
159
|
}),
|
|
157
160
|
mapping: {
|
|
158
161
|
settings: {
|
|
@@ -195,7 +198,7 @@ var purchaseWithLiFatId = {
|
|
|
195
198
|
}
|
|
196
199
|
]
|
|
197
200
|
},
|
|
198
|
-
eventId: "1700000902000
|
|
201
|
+
eventId: "ev-1700000902000",
|
|
199
202
|
conversionValue: {
|
|
200
203
|
currencyCode: "USD",
|
|
201
204
|
amount: "89.99"
|
package/dist/examples/index.mjs
CHANGED
|
@@ -43,10 +43,11 @@ var purchase = {
|
|
|
43
43
|
title: "Purchase",
|
|
44
44
|
description: "A completed order is sent to the LinkedIn Conversions API with conversion value, currency, and hashed email.",
|
|
45
45
|
in: getEvent("order complete", {
|
|
46
|
+
id: "ev-1700000900000",
|
|
46
47
|
timestamp: 17000009e5,
|
|
47
48
|
data: { total: 249.99, currency: "EUR" },
|
|
48
49
|
user: { email: "jane@example.com" },
|
|
49
|
-
source: { type: "
|
|
50
|
+
source: { type: "express", platform: "server" }
|
|
50
51
|
}),
|
|
51
52
|
mapping: {
|
|
52
53
|
settings: {
|
|
@@ -76,7 +77,7 @@ var purchase = {
|
|
|
76
77
|
}
|
|
77
78
|
]
|
|
78
79
|
},
|
|
79
|
-
eventId: "1700000900000
|
|
80
|
+
eventId: "ev-1700000900000",
|
|
80
81
|
conversionValue: {
|
|
81
82
|
currencyCode: "EUR",
|
|
82
83
|
amount: "249.99"
|
|
@@ -92,9 +93,10 @@ var lead = {
|
|
|
92
93
|
title: "Lead",
|
|
93
94
|
description: "A form submission is posted to LinkedIn as a conversion with the SHA-256 hashed email as the user identifier.",
|
|
94
95
|
in: getEvent("form submit", {
|
|
96
|
+
id: "ev-1700000901000",
|
|
95
97
|
timestamp: 1700000901e3,
|
|
96
98
|
user: { email: "user@example.com" },
|
|
97
|
-
source: { type: "
|
|
99
|
+
source: { type: "express", platform: "server" }
|
|
98
100
|
}),
|
|
99
101
|
mapping: void 0,
|
|
100
102
|
out: [
|
|
@@ -115,7 +117,7 @@ var lead = {
|
|
|
115
117
|
}
|
|
116
118
|
]
|
|
117
119
|
},
|
|
118
|
-
eventId: "1700000901000
|
|
120
|
+
eventId: "ev-1700000901000"
|
|
119
121
|
}
|
|
120
122
|
]
|
|
121
123
|
}),
|
|
@@ -127,11 +129,12 @@ var purchaseWithLiFatId = {
|
|
|
127
129
|
title: "Purchase with li_fat_id",
|
|
128
130
|
description: "A purchase is sent to LinkedIn with both the hashed email and the first-party li_fat_id tracking identifier.",
|
|
129
131
|
in: getEvent("order complete", {
|
|
132
|
+
id: "ev-1700000902000",
|
|
130
133
|
timestamp: 1700000902e3,
|
|
131
134
|
data: { total: 89.99, currency: "USD" },
|
|
132
135
|
user: { email: "buyer@co.com" },
|
|
133
136
|
context: { li_fat_id: ["abc123-fat-id", 0] },
|
|
134
|
-
source: { type: "
|
|
137
|
+
source: { type: "express", platform: "server" }
|
|
135
138
|
}),
|
|
136
139
|
mapping: {
|
|
137
140
|
settings: {
|
|
@@ -174,7 +177,7 @@ var purchaseWithLiFatId = {
|
|
|
174
177
|
}
|
|
175
178
|
]
|
|
176
179
|
},
|
|
177
|
-
eventId: "1700000902000
|
|
180
|
+
eventId: "ev-1700000902000",
|
|
178
181
|
conversionValue: {
|
|
179
182
|
currencyCode: "USD",
|
|
180
183
|
amount: "89.99"
|
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,{DestinationLinkedIn:()=>types_exports,default:()=>index_default,destinationLinkedIn:()=>destinationLinkedIn}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core=require("@walkeros/core"),import_server_core=require("@walkeros/server-core"),import_server_core2=require("@walkeros/server-core"),types_exports={},destinationLinkedIn={type:"linkedin",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,conversionRuleId:conversionRuleId}=settings;accessToken||logger.throw("Config settings accessToken missing"),conversionRuleId||logger.throw("Config settings conversionRuleId missing");const settingsConfig={...settings,accessToken:accessToken,conversionRuleId:conversionRuleId,apiVersion:settings.apiVersion||"202604"};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){const{accessToken:accessToken,conversionRuleId:conversionRuleId,apiVersion:apiVersion="202604",doNotHash:doNotHash,url:url="https://api.linkedin.com/rest/",user_data:user_data}=config.settings,userDataCustom=user_data?await(0,import_core.getMappingValue)(event,{map:user_data}):{},eventData=(0,import_core.isObject)(data)?data:{},userData={...(0,import_core.isObject)(userDataCustom)?userDataCustom:{},...(0,import_core.isObject)(eventData.user_data)?eventData.user_data:{}},email=(0,import_core.isString)(userData.email)?userData.email:(0,import_core.isString)(event.user.email)?event.user.email:void 0,userIds=[];if(email){const normalizedEmail=email.trim().toLowerCase(),idValue=
|
|
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,{DestinationLinkedIn:()=>types_exports,default:()=>index_default,destinationLinkedIn:()=>destinationLinkedIn}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core=require("@walkeros/core"),import_server_core=require("@walkeros/server-core"),import_server_core2=require("@walkeros/server-core"),types_exports={},destinationLinkedIn={type:"linkedin",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,conversionRuleId:conversionRuleId}=settings;accessToken||logger.throw("Config settings accessToken missing"),conversionRuleId||logger.throw("Config settings conversionRuleId missing");const settingsConfig={...settings,accessToken:accessToken,conversionRuleId:conversionRuleId,apiVersion:settings.apiVersion||"202604"};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){const{accessToken:accessToken,conversionRuleId:conversionRuleId,apiVersion:apiVersion="202604",doNotHash:doNotHash,url:url="https://api.linkedin.com/rest/",user_data:user_data}=config.settings,userDataCustom=user_data?await(0,import_core.getMappingValue)(event,{map:user_data}):{},eventData=(0,import_core.isObject)(data)?data:{},userData={...(0,import_core.isObject)(userDataCustom)?userDataCustom:{},...(0,import_core.isObject)(eventData.user_data)?eventData.user_data:{}},email=(0,import_core.isString)(userData.email)?userData.email:(0,import_core.isString)(event.user.email)?event.user.email:void 0,userIds=[];if(email){const normalizedEmail=email.trim().toLowerCase(),idValue=doNotHash?.includes("email")?normalizedEmail:await(0,import_server_core2.getHashServer)(normalizedEmail);userIds.push({idType:"SHA256_EMAIL",idValue:idValue})}const liFatIdRaw=userData.li_fat_id,liFatId=(0,import_core.isString)(liFatIdRaw)?liFatIdRaw:(0,import_core.isArray)(liFatIdRaw)&&(0,import_core.isString)(liFatIdRaw[0])?liFatIdRaw[0]:void 0;if(liFatId&&userIds.push({idType:"LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID",idValue:liFatId}),0===userIds.length)return;let userInfo;const firstName=userData.firstName,lastName=userData.lastName;(0,import_core.isString)(firstName)&&(0,import_core.isString)(lastName)&&firstName&&lastName&&(userInfo={firstName:firstName,lastName:lastName},(0,import_core.isString)(userData.title)&&userData.title&&(userInfo.title=userData.title),(0,import_core.isString)(userData.companyName)&&userData.companyName&&(userInfo.companyName=userData.companyName),(0,import_core.isString)(userData.countryCode)&&userData.countryCode&&(userInfo.countryCode=userData.countryCode));const mappingSettings=rule?.settings||{},conversionResolved=mappingSettings.conversion?await(0,import_core.getMappingValue)(event,mappingSettings.conversion):void 0,conversionOverride=(0,import_core.isObject)(conversionResolved)?conversionResolved:{},conversion=`urn:lla:llaPartnerConversion:${(0,import_core.isString)(conversionOverride.ruleId)?conversionOverride.ruleId:conversionRuleId}`;let conversionValue;const valueRaw=conversionOverride.value,currencyRaw=conversionOverride.currency;null!=valueRaw&&(conversionValue={currencyCode:(0,import_core.isString)(currencyRaw)?currencyRaw:"USD",amount:String(valueRaw)});const conversionEvent={conversion:conversion,conversionHappenedAt:event.timestamp,user:{userIds:userIds,...userInfo?{userInfo:userInfo}:{}},eventId:event.id};conversionValue&&(conversionEvent.conversionValue=conversionValue);const body={elements:[conversionEvent]},endpoint=`${url}conversionEvents`;logger.debug("Calling LinkedIn API",{endpoint:endpoint,method:"POST",conversion:conversion,eventId:event.id});const sendServerFn=env?.sendServer||import_server_core.sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0","X-RestLi-Method":"BATCH_CREATE","Linkedin-Version":apiVersion}});logger.debug("LinkedIn API response",{ok:!(0,import_core.isObject)(result)||result.ok}),(0,import_core.isObject)(result)&&!1===result.ok&&logger.throw(`LinkedIn API error: ${JSON.stringify(result)}`)}(event,context)},index_default=destinationLinkedIn;//# 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/types/index.ts"],"sourcesContent":["import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationLinkedIn from './types';\n\nexport const destinationLinkedIn: Destination = {\n type: 'linkedin',\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 destinationLinkedIn;\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, conversionRuleId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!conversionRuleId)\n logger.throw('Config settings conversionRuleId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n conversionRuleId,\n apiVersion: settings.apiVersion || '202604',\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n ConversionEvent,\n ConversionEventsRequest,\n ConversionValue,\n Env,\n Mapping,\n PushFn,\n UserIdentifier,\n UserInfo,\n} from './types';\nimport { getMappingValue, isArray, isObject, isString } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { getHashServer } from '@walkeros/server-core';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n accessToken,\n conversionRuleId,\n apiVersion = '202604',\n doNotHash,\n url = 'https://api.linkedin.com/rest/',\n user_data,\n } = config.settings!;\n\n // Resolve user data from settings-level mapping\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Merge user data sources: config mapping + event mapping data\n const eventData = isObject(data) ? data : {};\n const userData: Record<string, unknown> = {\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n ...(isObject(eventData.user_data) ? eventData.user_data : {}),\n };\n\n // Always try to get email from event.user.email if not already mapped\n const email = isString(userData.email)\n ? userData.email\n : isString(event.user.email)\n ? event.user.email\n : undefined;\n\n // Build userIds array\n const userIds: UserIdentifier[] = [];\n\n // SHA256_EMAIL\n if (email) {\n const normalizedEmail = email.trim().toLowerCase();\n const shouldHash = !doNotHash?.includes('email');\n const idValue = shouldHash\n ? await getHashServer(normalizedEmail)\n : normalizedEmail;\n\n userIds.push({\n idType: 'SHA256_EMAIL',\n idValue,\n });\n }\n\n // LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID from li_fat_id\n // Handle both string and context tuple [value, order] formats\n const liFatIdRaw = userData.li_fat_id;\n const liFatId = isString(liFatIdRaw)\n ? liFatIdRaw\n : isArray(liFatIdRaw) && isString(liFatIdRaw[0])\n ? liFatIdRaw[0]\n : undefined;\n if (liFatId) {\n userIds.push({\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: liFatId,\n });\n }\n\n // Skip event if no user identifiers\n if (userIds.length === 0) return;\n\n // Build optional userInfo\n let userInfo: UserInfo | undefined;\n const firstName = userData.firstName;\n const lastName = userData.lastName;\n if (isString(firstName) && isString(lastName) && firstName && lastName) {\n userInfo = { firstName, lastName };\n if (isString(userData.title) && userData.title)\n userInfo.title = userData.title;\n if (isString(userData.companyName) && userData.companyName)\n userInfo.companyName = userData.companyName;\n if (isString(userData.countryCode) && userData.countryCode)\n userInfo.countryCode = userData.countryCode;\n }\n\n // Resolve per-event conversion override\n const mappingSettings = (rule?.settings || {}) as Mapping;\n const conversionResolved = mappingSettings.conversion\n ? await getMappingValue(event, mappingSettings.conversion)\n : undefined;\n const conversionOverride = isObject(conversionResolved)\n ? conversionResolved\n : {};\n\n // Build conversion URN\n const ruleId = isString(conversionOverride.ruleId)\n ? conversionOverride.ruleId\n : conversionRuleId;\n const conversion = `urn:lla:llaPartnerConversion:${ruleId}`;\n\n // Build conversion value\n let conversionValue: ConversionValue | undefined;\n const valueRaw = conversionOverride.value;\n const currencyRaw = conversionOverride.currency;\n if (valueRaw !== undefined && valueRaw !== null) {\n conversionValue = {\n currencyCode: isString(currencyRaw) ? currencyRaw : 'USD',\n amount: String(valueRaw),\n };\n }\n\n // Construct the conversion event\n const conversionEvent: ConversionEvent = {\n conversion,\n conversionHappenedAt: event.timestamp,\n user: {\n userIds,\n ...(userInfo ? { userInfo } : {}),\n },\n eventId: event.id,\n };\n\n if (conversionValue) {\n conversionEvent.conversionValue = conversionValue;\n }\n\n // Construct request body\n const body: ConversionEventsRequest = {\n elements: [conversionEvent],\n };\n\n const endpoint = `${url}conversionEvents`;\n\n logger.debug('Calling LinkedIn API', {\n endpoint,\n method: 'POST',\n conversion,\n eventId: event.id,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n 'Linkedin-Version': apiVersion,\n },\n });\n\n logger.debug('LinkedIn API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`LinkedIn API error: ${JSON.stringify(result)}`);\n }\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 conversionRuleId: string;\n apiVersion?: string;\n doNotHash?: string[];\n url?: string;\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n conversion?: WalkerOSMapping.Value;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// LinkedIn API types\n\nexport type UserIdType =\n | 'SHA256_EMAIL'\n | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID'\n | 'ACXIOM_ID'\n | 'ORACLE_MOAT_ID';\n\nexport interface UserIdentifier {\n idType: UserIdType;\n idValue: string;\n}\n\nexport interface UserInfo {\n firstName: string;\n lastName: string;\n title?: string;\n companyName?: string;\n countryCode?: string;\n}\n\nexport interface ConversionUser {\n userIds: UserIdentifier[];\n userInfo?: UserInfo;\n}\n\nexport interface ConversionValue {\n currencyCode: string;\n amount: string;\n}\n\nexport interface ConversionEvent {\n conversion: string;\n conversionHappenedAt: number;\n conversionValue?: ConversionValue;\n user: ConversionUser;\n eventId?: string;\n}\n\nexport interface ConversionEventsRequest {\n elements: ConversionEvent[];\n}\n"],"mappings":"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","names":["import_server_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/push.ts","../src/types/index.ts"],"sourcesContent":["import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationLinkedIn from './types';\n\nexport const destinationLinkedIn: Destination = {\n type: 'linkedin',\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 destinationLinkedIn;\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, conversionRuleId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!conversionRuleId)\n logger.throw('Config settings conversionRuleId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n conversionRuleId,\n apiVersion: settings.apiVersion || '202604',\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n ConversionEvent,\n ConversionEventsRequest,\n ConversionValue,\n Env,\n Mapping,\n PushFn,\n UserIdentifier,\n UserInfo,\n} from './types';\nimport { getMappingValue, isArray, isObject, isString } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { getHashServer } from '@walkeros/server-core';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n accessToken,\n conversionRuleId,\n apiVersion = '202604',\n doNotHash,\n url = 'https://api.linkedin.com/rest/',\n user_data,\n } = config.settings!;\n\n // Resolve user data from settings-level mapping\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Merge user data sources: config mapping + event mapping data\n const eventData = isObject(data) ? data : {};\n const userData: Record<string, unknown> = {\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n ...(isObject(eventData.user_data) ? eventData.user_data : {}),\n };\n\n // Always try to get email from event.user.email if not already mapped\n const email = isString(userData.email)\n ? userData.email\n : isString(event.user.email)\n ? event.user.email\n : undefined;\n\n // Build userIds array\n const userIds: UserIdentifier[] = [];\n\n // SHA256_EMAIL\n if (email) {\n const normalizedEmail = email.trim().toLowerCase();\n const shouldHash = !doNotHash?.includes('email');\n const idValue = shouldHash\n ? await getHashServer(normalizedEmail)\n : normalizedEmail;\n\n userIds.push({\n idType: 'SHA256_EMAIL',\n idValue,\n });\n }\n\n // LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID from li_fat_id\n // Handle both string and context tuple [value, order] formats\n const liFatIdRaw = userData.li_fat_id;\n const liFatId = isString(liFatIdRaw)\n ? liFatIdRaw\n : isArray(liFatIdRaw) && isString(liFatIdRaw[0])\n ? liFatIdRaw[0]\n : undefined;\n if (liFatId) {\n userIds.push({\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: liFatId,\n });\n }\n\n // Skip event if no user identifiers\n if (userIds.length === 0) return;\n\n // Build optional userInfo\n let userInfo: UserInfo | undefined;\n const firstName = userData.firstName;\n const lastName = userData.lastName;\n if (isString(firstName) && isString(lastName) && firstName && lastName) {\n userInfo = { firstName, lastName };\n if (isString(userData.title) && userData.title)\n userInfo.title = userData.title;\n if (isString(userData.companyName) && userData.companyName)\n userInfo.companyName = userData.companyName;\n if (isString(userData.countryCode) && userData.countryCode)\n userInfo.countryCode = userData.countryCode;\n }\n\n // Resolve per-event conversion override\n const mappingSettings = (rule?.settings || {}) as Mapping;\n const conversionResolved = mappingSettings.conversion\n ? await getMappingValue(event, mappingSettings.conversion)\n : undefined;\n const conversionOverride = isObject(conversionResolved)\n ? conversionResolved\n : {};\n\n // Build conversion URN\n const ruleId = isString(conversionOverride.ruleId)\n ? conversionOverride.ruleId\n : conversionRuleId;\n const conversion = `urn:lla:llaPartnerConversion:${ruleId}`;\n\n // Build conversion value\n let conversionValue: ConversionValue | undefined;\n const valueRaw = conversionOverride.value;\n const currencyRaw = conversionOverride.currency;\n if (valueRaw !== undefined && valueRaw !== null) {\n conversionValue = {\n currencyCode: isString(currencyRaw) ? currencyRaw : 'USD',\n amount: String(valueRaw),\n };\n }\n\n // Construct the conversion event\n const conversionEvent: ConversionEvent = {\n conversion,\n conversionHappenedAt: event.timestamp,\n user: {\n userIds,\n ...(userInfo ? { userInfo } : {}),\n },\n eventId: event.id,\n };\n\n if (conversionValue) {\n conversionEvent.conversionValue = conversionValue;\n }\n\n // Construct request body\n const body: ConversionEventsRequest = {\n elements: [conversionEvent],\n };\n\n const endpoint = `${url}conversionEvents`;\n\n logger.debug('Calling LinkedIn API', {\n endpoint,\n method: 'POST',\n conversion,\n eventId: event.id,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n 'Linkedin-Version': apiVersion,\n },\n });\n\n logger.debug('LinkedIn API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`LinkedIn API error: ${JSON.stringify(result)}`);\n }\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 conversionRuleId: string;\n apiVersion?: string;\n doNotHash?: string[];\n url?: string;\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n conversion?: WalkerOSMapping.Value;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// LinkedIn API types\n\nexport type UserIdType =\n | 'SHA256_EMAIL'\n | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID'\n | 'ACXIOM_ID'\n | 'ORACLE_MOAT_ID';\n\nexport interface UserIdentifier {\n idType: UserIdType;\n idValue: string;\n}\n\nexport interface UserInfo {\n firstName: string;\n lastName: string;\n title?: string;\n companyName?: string;\n countryCode?: string;\n}\n\nexport interface ConversionUser {\n userIds: UserIdentifier[];\n userInfo?: UserInfo;\n}\n\nexport interface ConversionValue {\n currencyCode: string;\n amount: string;\n}\n\nexport interface ConversionEvent {\n conversion: string;\n conversionHappenedAt: number;\n conversionValue?: ConversionValue;\n user: ConversionUser;\n eventId?: string;\n}\n\nexport interface ConversionEventsRequest {\n elements: ConversionEvent[];\n}\n"],"mappings":"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","names":["import_server_core"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getMappingValue,isArray,isObject,isString}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{getHashServer}from"@walkeros/server-core";var types_exports={},destinationLinkedIn={type:"linkedin",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,conversionRuleId:conversionRuleId}=settings;accessToken||logger.throw("Config settings accessToken missing"),conversionRuleId||logger.throw("Config settings conversionRuleId missing");const settingsConfig={...settings,accessToken:accessToken,conversionRuleId:conversionRuleId,apiVersion:settings.apiVersion||"202604"};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){const{accessToken:accessToken,conversionRuleId:conversionRuleId,apiVersion:apiVersion="202604",doNotHash:doNotHash,url:url="https://api.linkedin.com/rest/",user_data:user_data}=config.settings,userDataCustom=user_data?await getMappingValue(event,{map:user_data}):{},eventData=isObject(data)?data:{},userData={...isObject(userDataCustom)?userDataCustom:{},...isObject(eventData.user_data)?eventData.user_data:{}},email=isString(userData.email)?userData.email:isString(event.user.email)?event.user.email:void 0,userIds=[];if(email){const normalizedEmail=email.trim().toLowerCase(),idValue=
|
|
1
|
+
import{getMappingValue,isArray,isObject,isString}from"@walkeros/core";import{sendServer}from"@walkeros/server-core";import{getHashServer}from"@walkeros/server-core";var types_exports={},destinationLinkedIn={type:"linkedin",config:{},async init({config:partialConfig,logger:logger}){const config=function(partialConfig={},logger){const settings=partialConfig.settings||{},{accessToken:accessToken,conversionRuleId:conversionRuleId}=settings;accessToken||logger.throw("Config settings accessToken missing"),conversionRuleId||logger.throw("Config settings conversionRuleId missing");const settingsConfig={...settings,accessToken:accessToken,conversionRuleId:conversionRuleId,apiVersion:settings.apiVersion||"202604"};return{...partialConfig,settings:settingsConfig}}(partialConfig,logger);return config},push:async(event,context)=>await async function(event,{config:config,rule:rule,data:data,env:env,logger:logger}){const{accessToken:accessToken,conversionRuleId:conversionRuleId,apiVersion:apiVersion="202604",doNotHash:doNotHash,url:url="https://api.linkedin.com/rest/",user_data:user_data}=config.settings,userDataCustom=user_data?await getMappingValue(event,{map:user_data}):{},eventData=isObject(data)?data:{},userData={...isObject(userDataCustom)?userDataCustom:{},...isObject(eventData.user_data)?eventData.user_data:{}},email=isString(userData.email)?userData.email:isString(event.user.email)?event.user.email:void 0,userIds=[];if(email){const normalizedEmail=email.trim().toLowerCase(),idValue=doNotHash?.includes("email")?normalizedEmail:await getHashServer(normalizedEmail);userIds.push({idType:"SHA256_EMAIL",idValue:idValue})}const liFatIdRaw=userData.li_fat_id,liFatId=isString(liFatIdRaw)?liFatIdRaw:isArray(liFatIdRaw)&&isString(liFatIdRaw[0])?liFatIdRaw[0]:void 0;if(liFatId&&userIds.push({idType:"LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID",idValue:liFatId}),0===userIds.length)return;let userInfo;const firstName=userData.firstName,lastName=userData.lastName;isString(firstName)&&isString(lastName)&&firstName&&lastName&&(userInfo={firstName:firstName,lastName:lastName},isString(userData.title)&&userData.title&&(userInfo.title=userData.title),isString(userData.companyName)&&userData.companyName&&(userInfo.companyName=userData.companyName),isString(userData.countryCode)&&userData.countryCode&&(userInfo.countryCode=userData.countryCode));const mappingSettings=rule?.settings||{},conversionResolved=mappingSettings.conversion?await getMappingValue(event,mappingSettings.conversion):void 0,conversionOverride=isObject(conversionResolved)?conversionResolved:{},conversion=`urn:lla:llaPartnerConversion:${isString(conversionOverride.ruleId)?conversionOverride.ruleId:conversionRuleId}`;let conversionValue;const valueRaw=conversionOverride.value,currencyRaw=conversionOverride.currency;null!=valueRaw&&(conversionValue={currencyCode:isString(currencyRaw)?currencyRaw:"USD",amount:String(valueRaw)});const conversionEvent={conversion:conversion,conversionHappenedAt:event.timestamp,user:{userIds:userIds,...userInfo?{userInfo:userInfo}:{}},eventId:event.id};conversionValue&&(conversionEvent.conversionValue=conversionValue);const body={elements:[conversionEvent]},endpoint=`${url}conversionEvents`;logger.debug("Calling LinkedIn API",{endpoint:endpoint,method:"POST",conversion:conversion,eventId:event.id});const sendServerFn=env?.sendServer||sendServer,result=await sendServerFn(endpoint,JSON.stringify(body),{headers:{Authorization:`Bearer ${accessToken}`,"Content-Type":"application/json","X-Restli-Protocol-Version":"2.0.0","X-RestLi-Method":"BATCH_CREATE","Linkedin-Version":apiVersion}});logger.debug("LinkedIn API response",{ok:!isObject(result)||result.ok}),isObject(result)&&!1===result.ok&&logger.throw(`LinkedIn API error: ${JSON.stringify(result)}`)}(event,context)},index_default=destinationLinkedIn;export{types_exports as DestinationLinkedIn,index_default as default,destinationLinkedIn};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/push.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, conversionRuleId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!conversionRuleId)\n logger.throw('Config settings conversionRuleId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n conversionRuleId,\n apiVersion: settings.apiVersion || '202604',\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n ConversionEvent,\n ConversionEventsRequest,\n ConversionValue,\n Env,\n Mapping,\n PushFn,\n UserIdentifier,\n UserInfo,\n} from './types';\nimport { getMappingValue, isArray, isObject, isString } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { getHashServer } from '@walkeros/server-core';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n accessToken,\n conversionRuleId,\n apiVersion = '202604',\n doNotHash,\n url = 'https://api.linkedin.com/rest/',\n user_data,\n } = config.settings!;\n\n // Resolve user data from settings-level mapping\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Merge user data sources: config mapping + event mapping data\n const eventData = isObject(data) ? data : {};\n const userData: Record<string, unknown> = {\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n ...(isObject(eventData.user_data) ? eventData.user_data : {}),\n };\n\n // Always try to get email from event.user.email if not already mapped\n const email = isString(userData.email)\n ? userData.email\n : isString(event.user.email)\n ? event.user.email\n : undefined;\n\n // Build userIds array\n const userIds: UserIdentifier[] = [];\n\n // SHA256_EMAIL\n if (email) {\n const normalizedEmail = email.trim().toLowerCase();\n const shouldHash = !doNotHash?.includes('email');\n const idValue = shouldHash\n ? await getHashServer(normalizedEmail)\n : normalizedEmail;\n\n userIds.push({\n idType: 'SHA256_EMAIL',\n idValue,\n });\n }\n\n // LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID from li_fat_id\n // Handle both string and context tuple [value, order] formats\n const liFatIdRaw = userData.li_fat_id;\n const liFatId = isString(liFatIdRaw)\n ? liFatIdRaw\n : isArray(liFatIdRaw) && isString(liFatIdRaw[0])\n ? liFatIdRaw[0]\n : undefined;\n if (liFatId) {\n userIds.push({\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: liFatId,\n });\n }\n\n // Skip event if no user identifiers\n if (userIds.length === 0) return;\n\n // Build optional userInfo\n let userInfo: UserInfo | undefined;\n const firstName = userData.firstName;\n const lastName = userData.lastName;\n if (isString(firstName) && isString(lastName) && firstName && lastName) {\n userInfo = { firstName, lastName };\n if (isString(userData.title) && userData.title)\n userInfo.title = userData.title;\n if (isString(userData.companyName) && userData.companyName)\n userInfo.companyName = userData.companyName;\n if (isString(userData.countryCode) && userData.countryCode)\n userInfo.countryCode = userData.countryCode;\n }\n\n // Resolve per-event conversion override\n const mappingSettings = (rule?.settings || {}) as Mapping;\n const conversionResolved = mappingSettings.conversion\n ? await getMappingValue(event, mappingSettings.conversion)\n : undefined;\n const conversionOverride = isObject(conversionResolved)\n ? conversionResolved\n : {};\n\n // Build conversion URN\n const ruleId = isString(conversionOverride.ruleId)\n ? conversionOverride.ruleId\n : conversionRuleId;\n const conversion = `urn:lla:llaPartnerConversion:${ruleId}`;\n\n // Build conversion value\n let conversionValue: ConversionValue | undefined;\n const valueRaw = conversionOverride.value;\n const currencyRaw = conversionOverride.currency;\n if (valueRaw !== undefined && valueRaw !== null) {\n conversionValue = {\n currencyCode: isString(currencyRaw) ? currencyRaw : 'USD',\n amount: String(valueRaw),\n };\n }\n\n // Construct the conversion event\n const conversionEvent: ConversionEvent = {\n conversion,\n conversionHappenedAt: event.timestamp,\n user: {\n userIds,\n ...(userInfo ? { userInfo } : {}),\n },\n eventId: event.id,\n };\n\n if (conversionValue) {\n conversionEvent.conversionValue = conversionValue;\n }\n\n // Construct request body\n const body: ConversionEventsRequest = {\n elements: [conversionEvent],\n };\n\n const endpoint = `${url}conversionEvents`;\n\n logger.debug('Calling LinkedIn API', {\n endpoint,\n method: 'POST',\n conversion,\n eventId: event.id,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n 'Linkedin-Version': apiVersion,\n },\n });\n\n logger.debug('LinkedIn API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`LinkedIn API error: ${JSON.stringify(result)}`);\n }\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 conversionRuleId: string;\n apiVersion?: string;\n doNotHash?: string[];\n url?: string;\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n conversion?: WalkerOSMapping.Value;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// LinkedIn API types\n\nexport type UserIdType =\n | 'SHA256_EMAIL'\n | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID'\n | 'ACXIOM_ID'\n | 'ORACLE_MOAT_ID';\n\nexport interface UserIdentifier {\n idType: UserIdType;\n idValue: string;\n}\n\nexport interface UserInfo {\n firstName: string;\n lastName: string;\n title?: string;\n companyName?: string;\n countryCode?: string;\n}\n\nexport interface ConversionUser {\n userIds: UserIdentifier[];\n userInfo?: UserInfo;\n}\n\nexport interface ConversionValue {\n currencyCode: string;\n amount: string;\n}\n\nexport interface ConversionEvent {\n conversion: string;\n conversionHappenedAt: number;\n conversionValue?: ConversionValue;\n user: ConversionUser;\n eventId?: string;\n}\n\nexport interface ConversionEventsRequest {\n elements: ConversionEvent[];\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationLinkedIn from './types';\n\nexport const destinationLinkedIn: Destination = {\n type: 'linkedin',\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 destinationLinkedIn;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/push.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, conversionRuleId } = settings;\n\n if (!accessToken) logger.throw('Config settings accessToken missing');\n if (!conversionRuleId)\n logger.throw('Config settings conversionRuleId missing');\n\n const settingsConfig: Settings = {\n ...settings,\n accessToken,\n conversionRuleId,\n apiVersion: settings.apiVersion || '202604',\n };\n\n return { ...partialConfig, settings: settingsConfig };\n}\n","import type {\n ConversionEvent,\n ConversionEventsRequest,\n ConversionValue,\n Env,\n Mapping,\n PushFn,\n UserIdentifier,\n UserInfo,\n} from './types';\nimport { getMappingValue, isArray, isObject, isString } from '@walkeros/core';\nimport { sendServer } from '@walkeros/server-core';\nimport { getHashServer } from '@walkeros/server-core';\n\nexport const push: PushFn = async function (\n event,\n { config, rule, data, env, logger },\n) {\n const {\n accessToken,\n conversionRuleId,\n apiVersion = '202604',\n doNotHash,\n url = 'https://api.linkedin.com/rest/',\n user_data,\n } = config.settings!;\n\n // Resolve user data from settings-level mapping\n const userDataCustom = user_data\n ? await getMappingValue(event, { map: user_data })\n : {};\n\n // Merge user data sources: config mapping + event mapping data\n const eventData = isObject(data) ? data : {};\n const userData: Record<string, unknown> = {\n ...(isObject(userDataCustom) ? userDataCustom : {}),\n ...(isObject(eventData.user_data) ? eventData.user_data : {}),\n };\n\n // Always try to get email from event.user.email if not already mapped\n const email = isString(userData.email)\n ? userData.email\n : isString(event.user.email)\n ? event.user.email\n : undefined;\n\n // Build userIds array\n const userIds: UserIdentifier[] = [];\n\n // SHA256_EMAIL\n if (email) {\n const normalizedEmail = email.trim().toLowerCase();\n const shouldHash = !doNotHash?.includes('email');\n const idValue = shouldHash\n ? await getHashServer(normalizedEmail)\n : normalizedEmail;\n\n userIds.push({\n idType: 'SHA256_EMAIL',\n idValue,\n });\n }\n\n // LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID from li_fat_id\n // Handle both string and context tuple [value, order] formats\n const liFatIdRaw = userData.li_fat_id;\n const liFatId = isString(liFatIdRaw)\n ? liFatIdRaw\n : isArray(liFatIdRaw) && isString(liFatIdRaw[0])\n ? liFatIdRaw[0]\n : undefined;\n if (liFatId) {\n userIds.push({\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: liFatId,\n });\n }\n\n // Skip event if no user identifiers\n if (userIds.length === 0) return;\n\n // Build optional userInfo\n let userInfo: UserInfo | undefined;\n const firstName = userData.firstName;\n const lastName = userData.lastName;\n if (isString(firstName) && isString(lastName) && firstName && lastName) {\n userInfo = { firstName, lastName };\n if (isString(userData.title) && userData.title)\n userInfo.title = userData.title;\n if (isString(userData.companyName) && userData.companyName)\n userInfo.companyName = userData.companyName;\n if (isString(userData.countryCode) && userData.countryCode)\n userInfo.countryCode = userData.countryCode;\n }\n\n // Resolve per-event conversion override\n const mappingSettings = (rule?.settings || {}) as Mapping;\n const conversionResolved = mappingSettings.conversion\n ? await getMappingValue(event, mappingSettings.conversion)\n : undefined;\n const conversionOverride = isObject(conversionResolved)\n ? conversionResolved\n : {};\n\n // Build conversion URN\n const ruleId = isString(conversionOverride.ruleId)\n ? conversionOverride.ruleId\n : conversionRuleId;\n const conversion = `urn:lla:llaPartnerConversion:${ruleId}`;\n\n // Build conversion value\n let conversionValue: ConversionValue | undefined;\n const valueRaw = conversionOverride.value;\n const currencyRaw = conversionOverride.currency;\n if (valueRaw !== undefined && valueRaw !== null) {\n conversionValue = {\n currencyCode: isString(currencyRaw) ? currencyRaw : 'USD',\n amount: String(valueRaw),\n };\n }\n\n // Construct the conversion event\n const conversionEvent: ConversionEvent = {\n conversion,\n conversionHappenedAt: event.timestamp,\n user: {\n userIds,\n ...(userInfo ? { userInfo } : {}),\n },\n eventId: event.id,\n };\n\n if (conversionValue) {\n conversionEvent.conversionValue = conversionValue;\n }\n\n // Construct request body\n const body: ConversionEventsRequest = {\n elements: [conversionEvent],\n };\n\n const endpoint = `${url}conversionEvents`;\n\n logger.debug('Calling LinkedIn API', {\n endpoint,\n method: 'POST',\n conversion,\n eventId: event.id,\n });\n\n const sendServerFn = (env as Env)?.sendServer || sendServer;\n const result = await sendServerFn(endpoint, JSON.stringify(body), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n 'Linkedin-Version': apiVersion,\n },\n });\n\n logger.debug('LinkedIn API response', {\n ok: isObject(result) ? result.ok : true,\n });\n\n if (isObject(result) && result.ok === false) {\n logger.throw(`LinkedIn API error: ${JSON.stringify(result)}`);\n }\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 conversionRuleId: string;\n apiVersion?: string;\n doNotHash?: string[];\n url?: string;\n user_data?: WalkerOSMapping.Map;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n conversion?: WalkerOSMapping.Value;\n}\n\nexport interface Env extends DestinationServer.Env {\n sendServer?: typeof sendServer;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport interface Destination extends DestinationServer.Destination<Types> {\n init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n settings: Settings;\n} & DestinationServer.Config<Types>;\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// LinkedIn API types\n\nexport type UserIdType =\n | 'SHA256_EMAIL'\n | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID'\n | 'ACXIOM_ID'\n | 'ORACLE_MOAT_ID';\n\nexport interface UserIdentifier {\n idType: UserIdType;\n idValue: string;\n}\n\nexport interface UserInfo {\n firstName: string;\n lastName: string;\n title?: string;\n companyName?: string;\n countryCode?: string;\n}\n\nexport interface ConversionUser {\n userIds: UserIdentifier[];\n userInfo?: UserInfo;\n}\n\nexport interface ConversionValue {\n currencyCode: string;\n amount: string;\n}\n\nexport interface ConversionEvent {\n conversion: string;\n conversionHappenedAt: number;\n conversionValue?: ConversionValue;\n user: ConversionUser;\n eventId?: string;\n}\n\nexport interface ConversionEventsRequest {\n elements: ConversionEvent[];\n}\n","import type { Destination } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\n\n// Types\nexport * as DestinationLinkedIn from './types';\n\nexport const destinationLinkedIn: Destination = {\n type: 'linkedin',\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 destinationLinkedIn;\n"],"mappings":"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","names":[]}
|
package/dist/walkerOS.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$meta": {
|
|
3
3
|
"package": "@walkeros/server-destination-linkedin",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0-next-1777463920154",
|
|
5
5
|
"type": "destination",
|
|
6
6
|
"platform": [
|
|
7
7
|
"server"
|
|
@@ -139,42 +139,28 @@
|
|
|
139
139
|
"entity": "child",
|
|
140
140
|
"data": {
|
|
141
141
|
"is": "subordinated"
|
|
142
|
-
},
|
|
143
|
-
"nested": [],
|
|
144
|
-
"context": {
|
|
145
|
-
"element": [
|
|
146
|
-
"child",
|
|
147
|
-
0
|
|
148
|
-
]
|
|
149
142
|
}
|
|
150
143
|
}
|
|
151
144
|
],
|
|
152
145
|
"consent": {
|
|
153
146
|
"functional": true
|
|
154
147
|
},
|
|
155
|
-
"id": "1700000901000
|
|
148
|
+
"id": "ev-1700000901000",
|
|
156
149
|
"trigger": "test",
|
|
157
150
|
"entity": "form",
|
|
158
151
|
"action": "submit",
|
|
159
152
|
"timestamp": 1700000901000,
|
|
160
153
|
"timing": 3.14,
|
|
161
|
-
"group": "gr0up",
|
|
162
|
-
"count": 1,
|
|
163
|
-
"version": {
|
|
164
|
-
"source": "3.4.1",
|
|
165
|
-
"tagging": 1
|
|
166
|
-
},
|
|
167
154
|
"source": {
|
|
168
|
-
"type": "
|
|
169
|
-
"
|
|
170
|
-
"previous_id": ""
|
|
155
|
+
"type": "express",
|
|
156
|
+
"platform": "server"
|
|
171
157
|
}
|
|
172
158
|
},
|
|
173
159
|
"out": [
|
|
174
160
|
[
|
|
175
161
|
"sendServer",
|
|
176
162
|
"https://api.linkedin.com/rest/conversionEvents",
|
|
177
|
-
"{\"elements\":[{\"conversion\":\"urn:lla:llaPartnerConversion:12345678\",\"conversionHappenedAt\":1700000901000,\"user\":{\"userIds\":[{\"idType\":\"SHA256_EMAIL\",\"idValue\":\"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514\"}]},\"eventId\":\"1700000901000
|
|
163
|
+
"{\"elements\":[{\"conversion\":\"urn:lla:llaPartnerConversion:12345678\",\"conversionHappenedAt\":1700000901000,\"user\":{\"userIds\":[{\"idType\":\"SHA256_EMAIL\",\"idValue\":\"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514\"}]},\"eventId\":\"ev-1700000901000\"}]}",
|
|
178
164
|
{
|
|
179
165
|
"headers": {
|
|
180
166
|
"Authorization": "Bearer s3cr3t",
|
|
@@ -262,22 +248,15 @@
|
|
|
262
248
|
"consent": {
|
|
263
249
|
"functional": true
|
|
264
250
|
},
|
|
265
|
-
"id": "1700000900000
|
|
251
|
+
"id": "ev-1700000900000",
|
|
266
252
|
"trigger": "load",
|
|
267
253
|
"entity": "order",
|
|
268
254
|
"action": "complete",
|
|
269
255
|
"timestamp": 1700000900000,
|
|
270
256
|
"timing": 3.14,
|
|
271
|
-
"group": "gr0up",
|
|
272
|
-
"count": 1,
|
|
273
|
-
"version": {
|
|
274
|
-
"source": "3.4.1",
|
|
275
|
-
"tagging": 1
|
|
276
|
-
},
|
|
277
257
|
"source": {
|
|
278
|
-
"type": "
|
|
279
|
-
"
|
|
280
|
-
"previous_id": ""
|
|
258
|
+
"type": "express",
|
|
259
|
+
"platform": "server"
|
|
281
260
|
}
|
|
282
261
|
},
|
|
283
262
|
"mapping": {
|
|
@@ -297,7 +276,7 @@
|
|
|
297
276
|
[
|
|
298
277
|
"sendServer",
|
|
299
278
|
"https://api.linkedin.com/rest/conversionEvents",
|
|
300
|
-
"{\"elements\":[{\"conversion\":\"urn:lla:llaPartnerConversion:12345678\",\"conversionHappenedAt\":1700000900000,\"user\":{\"userIds\":[{\"idType\":\"SHA256_EMAIL\",\"idValue\":\"8c87b489ce35cf2e2f39f80e282cb2e804932a56a213983eeeb428407d43b52d\"}]},\"eventId\":\"1700000900000
|
|
279
|
+
"{\"elements\":[{\"conversion\":\"urn:lla:llaPartnerConversion:12345678\",\"conversionHappenedAt\":1700000900000,\"user\":{\"userIds\":[{\"idType\":\"SHA256_EMAIL\",\"idValue\":\"8c87b489ce35cf2e2f39f80e282cb2e804932a56a213983eeeb428407d43b52d\"}]},\"eventId\":\"ev-1700000900000\",\"conversionValue\":{\"currencyCode\":\"EUR\",\"amount\":\"249.99\"}}]}",
|
|
301
280
|
{
|
|
302
281
|
"headers": {
|
|
303
282
|
"Authorization": "Bearer s3cr3t",
|
|
@@ -385,22 +364,15 @@
|
|
|
385
364
|
"consent": {
|
|
386
365
|
"functional": true
|
|
387
366
|
},
|
|
388
|
-
"id": "1700000902000
|
|
367
|
+
"id": "ev-1700000902000",
|
|
389
368
|
"trigger": "load",
|
|
390
369
|
"entity": "order",
|
|
391
370
|
"action": "complete",
|
|
392
371
|
"timestamp": 1700000902000,
|
|
393
372
|
"timing": 3.14,
|
|
394
|
-
"group": "gr0up",
|
|
395
|
-
"count": 1,
|
|
396
|
-
"version": {
|
|
397
|
-
"source": "3.4.1",
|
|
398
|
-
"tagging": 1
|
|
399
|
-
},
|
|
400
373
|
"source": {
|
|
401
|
-
"type": "
|
|
402
|
-
"
|
|
403
|
-
"previous_id": ""
|
|
374
|
+
"type": "express",
|
|
375
|
+
"platform": "server"
|
|
404
376
|
}
|
|
405
377
|
},
|
|
406
378
|
"mapping": {
|
|
@@ -429,7 +401,7 @@
|
|
|
429
401
|
[
|
|
430
402
|
"sendServer",
|
|
431
403
|
"https://api.linkedin.com/rest/conversionEvents",
|
|
432
|
-
"{\"elements\":[{\"conversion\":\"urn:lla:llaPartnerConversion:12345678\",\"conversionHappenedAt\":1700000902000,\"user\":{\"userIds\":[{\"idType\":\"SHA256_EMAIL\",\"idValue\":\"484c39bfb51212665d9673805c112b5ba04cbf0460b6d3f00bcdc18b92afed66\"},{\"idType\":\"LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID\",\"idValue\":\"abc123-fat-id\"}]},\"eventId\":\"1700000902000
|
|
404
|
+
"{\"elements\":[{\"conversion\":\"urn:lla:llaPartnerConversion:12345678\",\"conversionHappenedAt\":1700000902000,\"user\":{\"userIds\":[{\"idType\":\"SHA256_EMAIL\",\"idValue\":\"484c39bfb51212665d9673805c112b5ba04cbf0460b6d3f00bcdc18b92afed66\"},{\"idType\":\"LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID\",\"idValue\":\"abc123-fat-id\"}]},\"eventId\":\"ev-1700000902000\",\"conversionValue\":{\"currencyCode\":\"USD\",\"amount\":\"89.99\"}}]}",
|
|
433
405
|
{
|
|
434
406
|
"headers": {
|
|
435
407
|
"Authorization": "Bearer s3cr3t",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/server-destination-linkedin",
|
|
3
3
|
"description": "LinkedIn Conversions API server destination for walkerOS",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0-next-1777463920154",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"update": "npx npm-check-updates -u && npm update"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@walkeros/core": "
|
|
38
|
-
"@walkeros/server-core": "
|
|
37
|
+
"@walkeros/core": "4.0.0-next-1777463920154",
|
|
38
|
+
"@walkeros/server-core": "4.0.0-next-1777463920154"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@walkeros/collector": "
|
|
41
|
+
"@walkeros/collector": "4.0.0-next-1777463920154"
|
|
42
42
|
},
|
|
43
43
|
"repository": {
|
|
44
44
|
"url": "git+https://github.com/elbwalker/walkerOS.git",
|