@shware/analytics 3.6.4 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (407) hide show
  1. package/README.md +50 -3
  2. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  3. package/dist/constants/storage.cjs +12 -37
  4. package/dist/constants/storage.cjs.map +1 -1
  5. package/dist/constants/storage.d.cts +10 -8
  6. package/dist/constants/storage.d.cts.map +1 -0
  7. package/dist/constants/storage.d.mts +13 -0
  8. package/dist/constants/storage.d.mts.map +1 -0
  9. package/dist/constants/storage.mjs +12 -13
  10. package/dist/constants/storage.mjs.map +1 -1
  11. package/dist/feedback/index.cjs +14 -40
  12. package/dist/feedback/index.cjs.map +1 -1
  13. package/dist/feedback/index.d.cts +4 -4
  14. package/dist/feedback/index.d.cts.map +1 -0
  15. package/dist/feedback/index.d.mts +6 -0
  16. package/dist/feedback/index.d.mts.map +1 -0
  17. package/dist/feedback/index.mjs +12 -14
  18. package/dist/feedback/index.mjs.map +1 -1
  19. package/dist/hooks/use-app-analytics.cjs +46 -65
  20. package/dist/hooks/use-app-analytics.cjs.map +1 -1
  21. package/dist/hooks/use-app-analytics.d.cts +3 -1
  22. package/dist/hooks/use-app-analytics.d.cts.map +1 -0
  23. package/dist/hooks/use-app-analytics.d.mts +5 -0
  24. package/dist/hooks/use-app-analytics.d.mts.map +1 -0
  25. package/dist/hooks/use-app-analytics.mjs +41 -36
  26. package/dist/hooks/use-app-analytics.mjs.map +1 -1
  27. package/dist/hooks/use-click-id-persistence.cjs +43 -65
  28. package/dist/hooks/use-click-id-persistence.cjs.map +1 -1
  29. package/dist/hooks/use-click-id-persistence.d.cts +3 -1
  30. package/dist/hooks/use-click-id-persistence.d.cts.map +1 -0
  31. package/dist/hooks/use-click-id-persistence.d.mts +5 -0
  32. package/dist/hooks/use-click-id-persistence.d.mts.map +1 -0
  33. package/dist/hooks/use-click-id-persistence.mjs +40 -38
  34. package/dist/hooks/use-click-id-persistence.mjs.map +1 -1
  35. package/dist/hooks/use-outbound-click-analytics.cjs +33 -55
  36. package/dist/hooks/use-outbound-click-analytics.cjs.map +1 -1
  37. package/dist/hooks/use-outbound-click-analytics.d.cts +3 -1
  38. package/dist/hooks/use-outbound-click-analytics.d.cts.map +1 -0
  39. package/dist/hooks/{use-outbound-click-analytics.d.ts → use-outbound-click-analytics.d.mts} +3 -1
  40. package/dist/hooks/use-outbound-click-analytics.d.mts.map +1 -0
  41. package/dist/hooks/use-outbound-click-analytics.mjs +31 -29
  42. package/dist/hooks/use-outbound-click-analytics.mjs.map +1 -1
  43. package/dist/hooks/use-previous.cjs +11 -35
  44. package/dist/hooks/use-previous.cjs.map +1 -1
  45. package/dist/hooks/use-previous.d.cts +3 -1
  46. package/dist/hooks/use-previous.d.cts.map +1 -0
  47. package/dist/hooks/use-previous.d.mts +5 -0
  48. package/dist/hooks/use-previous.d.mts.map +1 -0
  49. package/dist/hooks/use-previous.mjs +9 -9
  50. package/dist/hooks/use-previous.mjs.map +1 -1
  51. package/dist/hooks/use-track-impression.cjs +24 -51
  52. package/dist/hooks/use-track-impression.cjs.map +1 -1
  53. package/dist/hooks/use-track-impression.d.cts +5 -6
  54. package/dist/hooks/use-track-impression.d.cts.map +1 -0
  55. package/dist/hooks/use-track-impression.d.mts +6 -0
  56. package/dist/hooks/use-track-impression.d.mts.map +1 -0
  57. package/dist/hooks/use-track-impression.mjs +22 -25
  58. package/dist/hooks/use-track-impression.mjs.map +1 -1
  59. package/dist/hooks/use-web-analytics.cjs +98 -109
  60. package/dist/hooks/use-web-analytics.cjs.map +1 -1
  61. package/dist/hooks/use-web-analytics.d.cts +3 -1
  62. package/dist/hooks/use-web-analytics.d.cts.map +1 -0
  63. package/dist/hooks/{use-web-analytics.d.ts → use-web-analytics.d.mts} +3 -1
  64. package/dist/hooks/use-web-analytics.d.mts.map +1 -0
  65. package/dist/hooks/use-web-analytics.mjs +93 -80
  66. package/dist/hooks/use-web-analytics.mjs.map +1 -1
  67. package/dist/index.cjs +28 -74
  68. package/dist/index.d.cts +11 -13
  69. package/dist/index.d.mts +11 -0
  70. package/dist/index.mjs +3 -34
  71. package/dist/link/index.cjs +31 -58
  72. package/dist/link/index.cjs.map +1 -1
  73. package/dist/link/index.d.cts +7 -7
  74. package/dist/link/index.d.cts.map +1 -0
  75. package/dist/link/index.d.mts +11 -0
  76. package/dist/link/index.d.mts.map +1 -0
  77. package/dist/link/index.mjs +28 -31
  78. package/dist/link/index.mjs.map +1 -1
  79. package/dist/native/fbsdk.cjs +12 -33
  80. package/dist/native/fbsdk.cjs.map +1 -1
  81. package/dist/native/fbsdk.d.cts +4 -4
  82. package/dist/native/fbsdk.d.cts.map +1 -0
  83. package/dist/native/{fbsdk.d.ts → fbsdk.d.mts} +4 -4
  84. package/dist/native/fbsdk.d.mts.map +1 -0
  85. package/dist/native/fbsdk.mjs +10 -7
  86. package/dist/native/fbsdk.mjs.map +1 -1
  87. package/dist/native/fingerprint.cjs +41 -64
  88. package/dist/native/fingerprint.cjs.map +1 -1
  89. package/dist/native/fingerprint.d.cts +22 -20
  90. package/dist/native/fingerprint.d.cts.map +1 -0
  91. package/dist/native/fingerprint.d.mts +28 -0
  92. package/dist/native/fingerprint.d.mts.map +1 -0
  93. package/dist/native/fingerprint.mjs +36 -42
  94. package/dist/native/fingerprint.mjs.map +1 -1
  95. package/dist/native/firebase.cjs +12 -39
  96. package/dist/native/firebase.cjs.map +1 -1
  97. package/dist/native/firebase.d.cts +4 -4
  98. package/dist/native/firebase.d.cts.map +1 -0
  99. package/dist/native/firebase.d.mts +6 -0
  100. package/dist/native/firebase.d.mts.map +1 -0
  101. package/dist/native/firebase.mjs +10 -13
  102. package/dist/native/firebase.mjs.map +1 -1
  103. package/dist/native/index.cjs +11 -45
  104. package/dist/native/index.d.cts +4 -7
  105. package/dist/native/index.d.mts +4 -0
  106. package/dist/native/index.mjs +2 -12
  107. package/dist/native/posthog.cjs +5 -30
  108. package/dist/native/posthog.cjs.map +1 -1
  109. package/dist/native/posthog.d.cts +3 -1
  110. package/dist/native/posthog.d.cts.map +1 -0
  111. package/dist/native/posthog.d.mts +5 -0
  112. package/dist/native/posthog.d.mts.map +1 -0
  113. package/dist/native/posthog.mjs +5 -6
  114. package/dist/native/posthog.mjs.map +1 -1
  115. package/dist/native/setup.cjs +91 -129
  116. package/dist/native/setup.cjs.map +1 -1
  117. package/dist/native/setup.d.cts +6 -6
  118. package/dist/native/setup.d.cts.map +1 -0
  119. package/dist/native/{setup.d.ts → setup.d.mts} +6 -6
  120. package/dist/native/setup.d.mts.map +1 -0
  121. package/dist/native/setup.mjs +83 -105
  122. package/dist/native/setup.mjs.map +1 -1
  123. package/dist/next/index.cjs +72 -145
  124. package/dist/next/index.cjs.map +1 -1
  125. package/dist/next/index.d.cts +18 -19
  126. package/dist/next/index.d.cts.map +1 -0
  127. package/dist/next/index.d.mts +21 -0
  128. package/dist/next/index.d.mts.map +1 -0
  129. package/dist/next/index.mjs +65 -107
  130. package/dist/next/index.mjs.map +1 -1
  131. package/dist/react-router/index.cjs +80 -144
  132. package/dist/react-router/index.cjs.map +1 -1
  133. package/dist/react-router/index.d.cts +18 -19
  134. package/dist/react-router/index.d.cts.map +1 -0
  135. package/dist/react-router/index.d.mts +21 -0
  136. package/dist/react-router/index.d.mts.map +1 -0
  137. package/dist/react-router/index.mjs +75 -115
  138. package/dist/react-router/index.mjs.map +1 -1
  139. package/dist/schema/index.cjs +188 -233
  140. package/dist/schema/index.cjs.map +1 -1
  141. package/dist/schema/index.d.cts +236 -235
  142. package/dist/schema/index.d.cts.map +1 -0
  143. package/dist/schema/index.d.mts +325 -0
  144. package/dist/schema/index.d.mts.map +1 -0
  145. package/dist/schema/index.mjs +178 -222
  146. package/dist/schema/index.mjs.map +1 -1
  147. package/dist/server/index.cjs +9 -40
  148. package/dist/server/index.d.cts +5 -9
  149. package/dist/server/index.d.mts +5 -0
  150. package/dist/server/index.mjs +5 -12
  151. package/dist/server/linkedin-conversions-api.cjs +66 -95
  152. package/dist/server/linkedin-conversions-api.cjs.map +1 -1
  153. package/dist/server/linkedin-conversions-api.d.cts +45 -45
  154. package/dist/server/linkedin-conversions-api.d.cts.map +1 -0
  155. package/dist/server/linkedin-conversions-api.d.mts +56 -0
  156. package/dist/server/linkedin-conversions-api.d.mts.map +1 -0
  157. package/dist/server/linkedin-conversions-api.mjs +63 -68
  158. package/dist/server/linkedin-conversions-api.mjs.map +1 -1
  159. package/dist/server/meta-conversions-api.cjs +157 -265
  160. package/dist/server/meta-conversions-api.cjs.map +1 -1
  161. package/dist/server/meta-conversions-api.d.cts +8 -9
  162. package/dist/server/meta-conversions-api.d.cts.map +1 -0
  163. package/dist/server/meta-conversions-api.d.mts +10 -0
  164. package/dist/server/meta-conversions-api.d.mts.map +1 -0
  165. package/dist/server/meta-conversions-api.mjs +151 -243
  166. package/dist/server/meta-conversions-api.mjs.map +1 -1
  167. package/dist/server/openai-conversions-api.cjs +69 -96
  168. package/dist/server/openai-conversions-api.cjs.map +1 -1
  169. package/dist/server/openai-conversions-api.d.cts +34 -34
  170. package/dist/server/openai-conversions-api.d.cts.map +1 -0
  171. package/dist/server/openai-conversions-api.d.mts +47 -0
  172. package/dist/server/openai-conversions-api.d.mts.map +1 -0
  173. package/dist/server/openai-conversions-api.mjs +65 -68
  174. package/dist/server/openai-conversions-api.mjs.map +1 -1
  175. package/dist/server/reddit-conversions-api.cjs +64 -91
  176. package/dist/server/reddit-conversions-api.cjs.map +1 -1
  177. package/dist/server/reddit-conversions-api.d.cts +61 -61
  178. package/dist/server/reddit-conversions-api.d.cts.map +1 -0
  179. package/dist/server/reddit-conversions-api.d.mts +75 -0
  180. package/dist/server/reddit-conversions-api.d.mts.map +1 -0
  181. package/dist/server/reddit-conversions-api.mjs +59 -62
  182. package/dist/server/reddit-conversions-api.mjs.map +1 -1
  183. package/dist/setup/index.cjs +34 -63
  184. package/dist/setup/index.cjs.map +1 -1
  185. package/dist/setup/index.d.cts +30 -30
  186. package/dist/setup/index.d.cts.map +1 -0
  187. package/dist/setup/index.d.mts +41 -0
  188. package/dist/setup/index.d.mts.map +1 -0
  189. package/dist/setup/index.mjs +31 -36
  190. package/dist/setup/index.mjs.map +1 -1
  191. package/dist/setup/session.cjs +70 -106
  192. package/dist/setup/session.cjs.map +1 -1
  193. package/dist/setup/session.d.cts +26 -24
  194. package/dist/setup/session.d.cts.map +1 -0
  195. package/dist/setup/session.d.mts +31 -0
  196. package/dist/setup/session.d.mts.map +1 -0
  197. package/dist/setup/session.mjs +68 -80
  198. package/dist/setup/session.mjs.map +1 -1
  199. package/dist/tanstack/index.cjs +86 -156
  200. package/dist/tanstack/index.cjs.map +1 -1
  201. package/dist/tanstack/index.d.cts +19 -20
  202. package/dist/tanstack/index.d.cts.map +1 -0
  203. package/dist/tanstack/index.d.mts +22 -0
  204. package/dist/tanstack/index.d.mts.map +1 -0
  205. package/dist/tanstack/index.mjs +81 -127
  206. package/dist/tanstack/index.mjs.map +1 -1
  207. package/dist/third-parties/google-analytics.cjs +18 -43
  208. package/dist/third-parties/google-analytics.cjs.map +1 -1
  209. package/dist/third-parties/google-analytics.d.cts +7 -7
  210. package/dist/third-parties/google-analytics.d.cts.map +1 -0
  211. package/dist/third-parties/google-analytics.d.mts +12 -0
  212. package/dist/third-parties/google-analytics.d.mts.map +1 -0
  213. package/dist/third-parties/google-analytics.mjs +16 -17
  214. package/dist/third-parties/google-analytics.mjs.map +1 -1
  215. package/dist/third-parties/ignored-events.cjs +35 -68
  216. package/dist/third-parties/ignored-events.cjs.map +1 -1
  217. package/dist/third-parties/ignored-events.d.cts +3 -1
  218. package/dist/third-parties/ignored-events.d.cts.map +1 -0
  219. package/dist/third-parties/ignored-events.d.mts +5 -0
  220. package/dist/third-parties/ignored-events.d.mts.map +1 -0
  221. package/dist/third-parties/ignored-events.mjs +34 -43
  222. package/dist/third-parties/ignored-events.mjs.map +1 -1
  223. package/dist/third-parties/index.cjs +16 -53
  224. package/dist/third-parties/index.d.cts +6 -12
  225. package/dist/third-parties/index.d.mts +6 -0
  226. package/dist/third-parties/index.mjs +1 -14
  227. package/dist/third-parties/linkedin-insight-tag.cjs +28 -50
  228. package/dist/third-parties/linkedin-insight-tag.cjs.map +1 -1
  229. package/dist/third-parties/linkedin-insight-tag.d.cts +8 -9
  230. package/dist/third-parties/linkedin-insight-tag.d.cts.map +1 -0
  231. package/dist/third-parties/{linkedin-insight-tag.d.ts → linkedin-insight-tag.d.mts} +8 -9
  232. package/dist/third-parties/linkedin-insight-tag.d.mts.map +1 -0
  233. package/dist/third-parties/linkedin-insight-tag.mjs +25 -23
  234. package/dist/third-parties/linkedin-insight-tag.mjs.map +1 -1
  235. package/dist/third-parties/meta-pixel.cjs +45 -66
  236. package/dist/third-parties/meta-pixel.cjs.map +1 -1
  237. package/dist/third-parties/meta-pixel.d.cts +7 -8
  238. package/dist/third-parties/meta-pixel.d.cts.map +1 -0
  239. package/dist/third-parties/meta-pixel.d.mts +12 -0
  240. package/dist/third-parties/meta-pixel.d.mts.map +1 -0
  241. package/dist/third-parties/meta-pixel.mjs +41 -38
  242. package/dist/third-parties/meta-pixel.mjs.map +1 -1
  243. package/dist/third-parties/openai-pixel.cjs +63 -68
  244. package/dist/third-parties/openai-pixel.cjs.map +1 -1
  245. package/dist/third-parties/openai-pixel.d.cts +7 -8
  246. package/dist/third-parties/openai-pixel.d.cts.map +1 -0
  247. package/dist/third-parties/{openai-pixel.d.ts → openai-pixel.d.mts} +7 -8
  248. package/dist/third-parties/openai-pixel.d.mts.map +1 -0
  249. package/dist/third-parties/openai-pixel.mjs +60 -41
  250. package/dist/third-parties/openai-pixel.mjs.map +1 -1
  251. package/dist/third-parties/posthog.cjs +23 -43
  252. package/dist/third-parties/posthog.cjs.map +1 -1
  253. package/dist/third-parties/posthog.d.cts +5 -5
  254. package/dist/third-parties/posthog.d.cts.map +1 -0
  255. package/dist/third-parties/{posthog.d.ts → posthog.d.mts} +5 -5
  256. package/dist/third-parties/posthog.d.mts.map +1 -0
  257. package/dist/third-parties/posthog.mjs +20 -16
  258. package/dist/third-parties/posthog.mjs.map +1 -1
  259. package/dist/third-parties/reddit-pixel.cjs +37 -58
  260. package/dist/third-parties/reddit-pixel.cjs.map +1 -1
  261. package/dist/third-parties/reddit-pixel.d.cts +7 -8
  262. package/dist/third-parties/reddit-pixel.d.cts.map +1 -0
  263. package/dist/third-parties/reddit-pixel.d.mts +12 -0
  264. package/dist/third-parties/reddit-pixel.d.mts.map +1 -0
  265. package/dist/third-parties/reddit-pixel.mjs +33 -30
  266. package/dist/third-parties/reddit-pixel.mjs.map +1 -1
  267. package/dist/track/fbq.cjs +179 -135
  268. package/dist/track/fbq.cjs.map +1 -1
  269. package/dist/track/fbq.d.cts +234 -233
  270. package/dist/track/fbq.d.cts.map +1 -0
  271. package/dist/track/fbq.d.mts +280 -0
  272. package/dist/track/fbq.d.mts.map +1 -0
  273. package/dist/track/fbq.mjs +176 -108
  274. package/dist/track/fbq.mjs.map +1 -1
  275. package/dist/track/gtag.cjs +63 -86
  276. package/dist/track/gtag.cjs.map +1 -1
  277. package/dist/track/gtag.d.cts +682 -682
  278. package/dist/track/gtag.d.cts.map +1 -0
  279. package/dist/track/gtag.d.mts +762 -0
  280. package/dist/track/gtag.d.mts.map +1 -0
  281. package/dist/track/gtag.mjs +62 -61
  282. package/dist/track/gtag.mjs.map +1 -1
  283. package/dist/track/index.cjs +111 -136
  284. package/dist/track/index.cjs.map +1 -1
  285. package/dist/track/index.d.cts +8 -8
  286. package/dist/track/index.d.cts.map +1 -0
  287. package/dist/track/{index.d.ts → index.d.mts} +8 -8
  288. package/dist/track/index.d.mts.map +1 -0
  289. package/dist/track/index.mjs +105 -106
  290. package/dist/track/index.mjs.map +1 -1
  291. package/dist/track/lintrk.cjs +0 -19
  292. package/dist/track/lintrk.d.cts +12 -10
  293. package/dist/track/lintrk.d.cts.map +1 -0
  294. package/dist/track/lintrk.d.mts +14 -0
  295. package/dist/track/lintrk.d.mts.map +1 -0
  296. package/dist/track/lintrk.mjs +1 -1
  297. package/dist/track/oaiq.cjs +153 -146
  298. package/dist/track/oaiq.cjs.map +1 -1
  299. package/dist/track/oaiq.d.cts +65 -64
  300. package/dist/track/oaiq.d.cts.map +1 -0
  301. package/dist/track/oaiq.d.mts +112 -0
  302. package/dist/track/oaiq.d.mts.map +1 -0
  303. package/dist/track/oaiq.mjs +149 -118
  304. package/dist/track/oaiq.mjs.map +1 -1
  305. package/dist/track/rdt.cjs +66 -110
  306. package/dist/track/rdt.cjs.map +1 -1
  307. package/dist/track/rdt.d.cts +74 -73
  308. package/dist/track/rdt.d.cts.map +1 -0
  309. package/dist/track/rdt.d.mts +97 -0
  310. package/dist/track/rdt.d.mts.map +1 -0
  311. package/dist/track/rdt.mjs +63 -83
  312. package/dist/track/rdt.mjs.map +1 -1
  313. package/dist/track/types.cjs +0 -19
  314. package/dist/track/types.d.cts +140 -111
  315. package/dist/track/types.d.cts.map +1 -0
  316. package/dist/track/types.d.mts +171 -0
  317. package/dist/track/types.d.mts.map +1 -0
  318. package/dist/track/types.mjs +1 -1
  319. package/dist/utils/field.cjs +8 -32
  320. package/dist/utils/field.cjs.map +1 -1
  321. package/dist/utils/field.d.cts +3 -1
  322. package/dist/utils/field.d.cts.map +1 -0
  323. package/dist/utils/{field.d.ts → field.d.mts} +3 -1
  324. package/dist/utils/field.d.mts.map +1 -0
  325. package/dist/utils/field.mjs +7 -7
  326. package/dist/utils/field.mjs.map +1 -1
  327. package/dist/utils/stripe.cjs +25 -49
  328. package/dist/utils/stripe.cjs.map +1 -1
  329. package/dist/utils/stripe.d.cts +3 -1
  330. package/dist/utils/stripe.d.cts.map +1 -0
  331. package/dist/utils/{stripe.d.ts → stripe.d.mts} +3 -1
  332. package/dist/utils/stripe.d.mts.map +1 -0
  333. package/dist/utils/stripe.mjs +23 -23
  334. package/dist/utils/stripe.mjs.map +1 -1
  335. package/dist/visitor/index.cjs +54 -86
  336. package/dist/visitor/index.cjs.map +1 -1
  337. package/dist/visitor/index.d.cts +4 -5
  338. package/dist/visitor/index.d.cts.map +1 -0
  339. package/dist/visitor/{index.d.ts → index.d.mts} +4 -5
  340. package/dist/visitor/index.d.mts.map +1 -0
  341. package/dist/visitor/index.mjs +51 -59
  342. package/dist/visitor/index.mjs.map +1 -1
  343. package/dist/visitor/types.cjs +0 -19
  344. package/dist/visitor/types.d.cts +15 -14
  345. package/dist/visitor/types.d.cts.map +1 -0
  346. package/dist/visitor/types.d.mts +21 -0
  347. package/dist/visitor/types.d.mts.map +1 -0
  348. package/dist/visitor/types.mjs +1 -1
  349. package/dist/web/index.cjs +108 -148
  350. package/dist/web/index.cjs.map +1 -1
  351. package/dist/web/index.d.cts +5 -6
  352. package/dist/web/index.d.cts.map +1 -0
  353. package/dist/web/index.d.mts +9 -0
  354. package/dist/web/index.d.mts.map +1 -0
  355. package/dist/web/index.mjs +101 -109
  356. package/dist/web/index.mjs.map +1 -1
  357. package/package.json +102 -49
  358. package/dist/constants/storage.d.ts +0 -11
  359. package/dist/feedback/index.d.ts +0 -6
  360. package/dist/hooks/use-app-analytics.d.ts +0 -3
  361. package/dist/hooks/use-click-id-persistence.d.ts +0 -3
  362. package/dist/hooks/use-previous.d.ts +0 -3
  363. package/dist/hooks/use-track-impression.d.ts +0 -7
  364. package/dist/index.cjs.map +0 -1
  365. package/dist/index.d.ts +0 -13
  366. package/dist/index.mjs.map +0 -1
  367. package/dist/link/index.d.ts +0 -11
  368. package/dist/native/fingerprint.d.ts +0 -26
  369. package/dist/native/firebase.d.ts +0 -6
  370. package/dist/native/index.cjs.map +0 -1
  371. package/dist/native/index.d.ts +0 -7
  372. package/dist/native/index.mjs.map +0 -1
  373. package/dist/native/posthog.d.ts +0 -3
  374. package/dist/next/index.d.ts +0 -22
  375. package/dist/react-router/index.d.ts +0 -22
  376. package/dist/schema/index.d.ts +0 -324
  377. package/dist/server/index.cjs.map +0 -1
  378. package/dist/server/index.d.ts +0 -9
  379. package/dist/server/index.mjs.map +0 -1
  380. package/dist/server/linkedin-conversions-api.d.ts +0 -56
  381. package/dist/server/meta-conversions-api.d.ts +0 -11
  382. package/dist/server/openai-conversions-api.d.ts +0 -47
  383. package/dist/server/reddit-conversions-api.d.ts +0 -75
  384. package/dist/setup/index.d.ts +0 -41
  385. package/dist/setup/session.d.ts +0 -29
  386. package/dist/tanstack/index.d.ts +0 -23
  387. package/dist/third-parties/google-analytics.d.ts +0 -12
  388. package/dist/third-parties/ignored-events.d.ts +0 -3
  389. package/dist/third-parties/index.cjs.map +0 -1
  390. package/dist/third-parties/index.d.ts +0 -12
  391. package/dist/third-parties/index.mjs.map +0 -1
  392. package/dist/third-parties/meta-pixel.d.ts +0 -13
  393. package/dist/third-parties/reddit-pixel.d.ts +0 -13
  394. package/dist/track/fbq.d.ts +0 -279
  395. package/dist/track/gtag.d.ts +0 -762
  396. package/dist/track/lintrk.cjs.map +0 -1
  397. package/dist/track/lintrk.d.ts +0 -12
  398. package/dist/track/lintrk.mjs.map +0 -1
  399. package/dist/track/oaiq.d.ts +0 -111
  400. package/dist/track/rdt.d.ts +0 -96
  401. package/dist/track/types.cjs.map +0 -1
  402. package/dist/track/types.d.ts +0 -142
  403. package/dist/track/types.mjs.map +0 -1
  404. package/dist/visitor/types.cjs.map +0 -1
  405. package/dist/visitor/types.d.ts +0 -20
  406. package/dist/visitor/types.mjs.map +0 -1
  407. package/dist/web/index.d.ts +0 -10
@@ -1,98 +1,69 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/server/linkedin-conversions-api.ts
21
- var linkedin_conversions_api_exports = {};
22
- __export(linkedin_conversions_api_exports, {
23
- sendEvents: () => sendEvents
24
- });
25
- module.exports = __toCommonJS(linkedin_conversions_api_exports);
26
- var import_node_crypto = require("crypto");
27
- var import_utils = require("@shware/utils");
28
- var import_ignored_events = require("../third-parties/ignored-events.cjs");
29
- var import_field = require("../utils/field.cjs");
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_third_parties_ignored_events = require("../third-parties/ignored-events.cjs");
3
+ const require_utils_field = require("../utils/field.cjs");
4
+ let _shware_utils = require("@shware/utils");
5
+ let node_crypto = require("node:crypto");
6
+ //#region src/server/linkedin-conversions-api.ts
7
+ /**
8
+ * Conversions API Payload Builder: https://www.linkedin.com/developers/payload-builder
9
+ * https://learn.microsoft.com/en-us/linkedin/marketing/conversions/conversions-overview?view=li-lms-2025-09
10
+ */
30
11
  async function sendEvents(accessToken, config, events, data = {}) {
31
- const eventNames = Object.keys(config);
32
- const address = (0, import_field.getFirst)(data.address);
33
- const userIds = [];
34
- const externalIds = data.user_id ? [data.user_id] : void 0;
35
- const userInfo = address && address.first_name && address.last_name ? {
36
- firstName: address.first_name,
37
- lastName: address.last_name,
38
- countryCode: address.country
39
- } : void 0;
40
- if (data.email) {
41
- const email = (0, import_field.getFirst)(data.email);
42
- if (email)
43
- userIds.push({
44
- idType: "SHA256_EMAIL",
45
- idValue: (0, import_node_crypto.createHash)("sha256").update(email).digest("hex")
46
- });
47
- }
48
- const dto = {
49
- elements: events.filter((event) => eventNames.includes(event.name) && !import_ignored_events.IGNORED_EVENTS.includes(event.name)).map((event) => {
50
- var _a, _b, _c, _d;
51
- return {
52
- eventId: event.id,
53
- conversion: `urn:lla:llaPartnerConversion:${config[event.name]}`,
54
- conversionHappenedAt: Date.now(),
55
- conversionValue: {
56
- currencyCode: ((_b = (_a = event.properties) == null ? void 0 : _a.currency) == null ? void 0 : _b.toUpperCase()) ?? "USD",
57
- amount: ((_d = (_c = event.properties) == null ? void 0 : _c.value) == null ? void 0 : _d.toString()) ?? "0"
58
- },
59
- user: {
60
- userIds: event.tags.li_fat_id ? [
61
- {
62
- idType: "LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID",
63
- idValue: event.tags.li_fat_id
64
- },
65
- ...userIds
66
- ] : userIds,
67
- userInfo,
68
- externalIds
69
- }
70
- };
71
- })
72
- };
73
- if (dto.elements.length === 0) return;
74
- try {
75
- const response = await (0, import_utils.fetch)("https://api.linkedin.com/rest/conversionEvents", {
76
- method: "POST",
77
- headers: {
78
- Authorization: `Bearer ${accessToken}`,
79
- "Content-Type": "application/json",
80
- "LinkedIn-Version": "202509",
81
- "X-Restli-Protocol-Version": "2.0.0",
82
- "X-RestLi-Method": "BATCH_CREATE"
83
- },
84
- body: JSON.stringify(dto)
85
- });
86
- if (response.ok) return;
87
- const { status } = response;
88
- const message = await response.text();
89
- console.error(`Failed to send LinkedIn conversion, status: ${status}, body: ${message}`);
90
- } catch (error) {
91
- console.error("Failed to send LinkedIn conversion, network error:", error);
92
- }
12
+ const eventNames = Object.keys(config);
13
+ const address = require_utils_field.getFirst(data.address);
14
+ const userIds = [];
15
+ const externalIds = data.user_id ? [data.user_id] : void 0;
16
+ const userInfo = address && address.first_name && address.last_name ? {
17
+ firstName: address.first_name,
18
+ lastName: address.last_name,
19
+ countryCode: address.country
20
+ } : void 0;
21
+ if (data.email) {
22
+ const email = require_utils_field.getFirst(data.email);
23
+ if (email) userIds.push({
24
+ idType: "SHA256_EMAIL",
25
+ idValue: (0, node_crypto.createHash)("sha256").update(email).digest("hex")
26
+ });
27
+ }
28
+ const dto = { elements: events.filter((event) => eventNames.includes(event.name) && !require_third_parties_ignored_events.IGNORED_EVENTS.includes(event.name)).map((event) => ({
29
+ eventId: event.id,
30
+ conversion: `urn:lla:llaPartnerConversion:${config[event.name]}`,
31
+ conversionHappenedAt: Date.now(),
32
+ conversionValue: {
33
+ currencyCode: event.properties?.currency?.toUpperCase() ?? "USD",
34
+ amount: event.properties?.value?.toString() ?? "0"
35
+ },
36
+ user: {
37
+ userIds: event.tags.li_fat_id ? [{
38
+ idType: "LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID",
39
+ idValue: event.tags.li_fat_id
40
+ }, ...userIds] : userIds,
41
+ userInfo,
42
+ externalIds
43
+ }
44
+ })) };
45
+ if (dto.elements.length === 0) return;
46
+ try {
47
+ const response = await (0, _shware_utils.fetch)("https://api.linkedin.com/rest/conversionEvents", {
48
+ method: "POST",
49
+ headers: {
50
+ Authorization: `Bearer ${accessToken}`,
51
+ "Content-Type": "application/json",
52
+ "LinkedIn-Version": "202509",
53
+ "X-Restli-Protocol-Version": "2.0.0",
54
+ "X-RestLi-Method": "BATCH_CREATE"
55
+ },
56
+ body: JSON.stringify(dto)
57
+ });
58
+ if (response.ok) return;
59
+ const { status } = response;
60
+ const message = await response.text();
61
+ console.error(`Failed to send LinkedIn conversion, status: ${status}, body: ${message}`);
62
+ } catch (error) {
63
+ console.error("Failed to send LinkedIn conversion, network error:", error);
64
+ }
93
65
  }
94
- // Annotate the CommonJS export names for ESM import in node:
95
- 0 && (module.exports = {
96
- sendEvents
97
- });
66
+ //#endregion
67
+ exports.sendEvents = sendEvents;
68
+
98
69
  //# sourceMappingURL=linkedin-conversions-api.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server/linkedin-conversions-api.ts"],"sourcesContent":["/**\n * Conversions API Payload Builder: https://www.linkedin.com/developers/payload-builder\n * https://learn.microsoft.com/en-us/linkedin/marketing/conversions/conversions-overview?view=li-lms-2025-09\n */\nimport { createHash } from 'node:crypto';\nimport { fetch } from '@shware/utils';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport type { TrackEvent, UserProvidedData } from '../track/types';\nimport { getFirst } from '../utils/field';\n\ntype UserIdType =\n | 'SHA256_EMAIL'\n | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID'\n | 'ACXIOM_ID'\n | 'ORACLE_MOAT_ID';\n\nexport interface CreateLinkedinEventDTO {\n /**\n * For any conversion that you want to send through multiple methods, such as Insight Tag and\n * Conversions API, you must create a conversion rule for each data source (browser and server).\n * Then, you can implement a logic to pick up the eventId from the browser and send it with the\n * corresponding event from your server. If we receive an Insight Tag event and a Conversions API\n * event from the same account with the same eventId, we discard the Conversions API event and\n * count only the Insight Tag event in campaign reporting.\n */\n eventId?: string;\n\n /**\n * Replace <id> with the conversion ID extracted when creating the conversion rule\n * (e.g. urn:lla:llaPartnerConversion:<id>).\n */\n conversion: `urn:lla:llaPartnerConversion:${number}`;\n\n /** Epoch timestamp in milliseconds at which the conversion event happened. */\n conversionHappenedAt: number;\n conversionValue: { currencyCode: string; amount: string };\n user: {\n userIds: { idType: UserIdType; idValue: string }[];\n userInfo?: {\n firstName?: string;\n lastName?: string;\n companyName?: string;\n countryCode?: string;\n title?: string;\n };\n\n /**\n * The maximum supported size of the list is 1 at the moment. If the list contains multiple\n * values, only the first value will be used.\n */\n externalIds?: [string, ...string[]];\n\n /**\n * This is generated when users submit the Linkedin Lead-gen form\n * (e.g. urn:li:leadGenFormResponse:<id>).\n */\n lead?: `urn:li:leadGenFormResponse:${string}`;\n };\n}\n\nexport interface CreateMultipleLinkedinEventsDTO {\n elements: CreateLinkedinEventDTO[];\n}\n\nexport type LinkedinConversionConfig = Record<Lowercase<string>, number>;\n\nexport async function sendEvents(\n accessToken: string,\n config: LinkedinConversionConfig,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n events: TrackEvent<any>[],\n data: UserProvidedData = {}\n) {\n const eventNames = Object.keys(config);\n const address = getFirst(data.address);\n const userIds: { idType: UserIdType; idValue: string }[] = [];\n const externalIds: [string, ...string[]] | undefined = data.user_id ? [data.user_id] : undefined;\n const userInfo =\n address && address.first_name && address.last_name\n ? {\n firstName: address.first_name,\n lastName: address.last_name,\n countryCode: address.country,\n }\n : undefined;\n\n if (data.email) {\n const email = getFirst(data.email);\n if (email)\n userIds.push({\n idType: 'SHA256_EMAIL',\n idValue: createHash('sha256').update(email).digest('hex'),\n });\n }\n\n const dto: CreateMultipleLinkedinEventsDTO = {\n elements: events\n .filter((event) => eventNames.includes(event.name) && !IGNORED_EVENTS.includes(event.name))\n .map((event) => ({\n eventId: event.id,\n conversion: `urn:lla:llaPartnerConversion:${config[event.name]}`,\n conversionHappenedAt: Date.now(),\n conversionValue: {\n currencyCode: event.properties?.currency?.toUpperCase() ?? 'USD',\n amount: event.properties?.value?.toString() ?? '0',\n },\n user: {\n userIds: event.tags.li_fat_id\n ? [\n {\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: event.tags.li_fat_id,\n },\n ...userIds,\n ]\n : userIds,\n userInfo,\n externalIds,\n },\n })),\n };\n\n if (dto.elements.length === 0) return;\n try {\n const response = await fetch('https://api.linkedin.com/rest/conversionEvents', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'LinkedIn-Version': '202509',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n },\n body: JSON.stringify(dto),\n });\n\n if (response.ok) return;\n const { status } = response;\n const message = await response.text();\n console.error(`Failed to send LinkedIn conversion, status: ${status}, body: ${message}`);\n } catch (error) {\n console.error('Failed to send LinkedIn conversion, network error:', error);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,yBAA2B;AAC3B,mBAAsB;AACtB,4BAA+B;AAE/B,mBAAyB;AA0DzB,eAAsB,WACpB,aACA,QAEA,QACA,OAAyB,CAAC,GAC1B;AACA,QAAM,aAAa,OAAO,KAAK,MAAM;AACrC,QAAM,cAAU,uBAAS,KAAK,OAAO;AACrC,QAAM,UAAqD,CAAC;AAC5D,QAAM,cAAiD,KAAK,UAAU,CAAC,KAAK,OAAO,IAAI;AACvF,QAAM,WACJ,WAAW,QAAQ,cAAc,QAAQ,YACrC;AAAA,IACE,WAAW,QAAQ;AAAA,IACnB,UAAU,QAAQ;AAAA,IAClB,aAAa,QAAQ;AAAA,EACvB,IACA;AAEN,MAAI,KAAK,OAAO;AACd,UAAM,YAAQ,uBAAS,KAAK,KAAK;AACjC,QAAI;AACF,cAAQ,KAAK;AAAA,QACX,QAAQ;AAAA,QACR,aAAS,+BAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAAA,MAC1D,CAAC;AAAA,EACL;AAEA,QAAM,MAAuC;AAAA,IAC3C,UAAU,OACP,OAAO,CAAC,UAAU,WAAW,SAAS,MAAM,IAAI,KAAK,CAAC,qCAAe,SAAS,MAAM,IAAI,CAAC,EACzF,IAAI,CAAC,UAAO;AAlGnB;AAkGuB;AAAA,QACf,SAAS,MAAM;AAAA,QACf,YAAY,gCAAgC,OAAO,MAAM,IAAI,CAAC;AAAA,QAC9D,sBAAsB,KAAK,IAAI;AAAA,QAC/B,iBAAiB;AAAA,UACf,gBAAc,iBAAM,eAAN,mBAAkB,aAAlB,mBAA4B,kBAAiB;AAAA,UAC3D,UAAQ,iBAAM,eAAN,mBAAkB,UAAlB,mBAAyB,eAAc;AAAA,QACjD;AAAA,QACA,MAAM;AAAA,UACJ,SAAS,MAAM,KAAK,YAChB;AAAA,YACE;AAAA,cACE,QAAQ;AAAA,cACR,SAAS,MAAM,KAAK;AAAA,YACtB;AAAA,YACA,GAAG;AAAA,UACL,IACA;AAAA,UACJ;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,KAAE;AAAA,EACN;AAEA,MAAI,IAAI,SAAS,WAAW,EAAG;AAC/B,MAAI;AACF,UAAM,WAAW,UAAM,oBAAM,kDAAkD;AAAA,MAC7E,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,WAAW;AAAA,QACpC,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,QACpB,6BAA6B;AAAA,QAC7B,mBAAmB;AAAA,MACrB;AAAA,MACA,MAAM,KAAK,UAAU,GAAG;AAAA,IAC1B,CAAC;AAED,QAAI,SAAS,GAAI;AACjB,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,UAAU,MAAM,SAAS,KAAK;AACpC,YAAQ,MAAM,+CAA+C,MAAM,WAAW,OAAO,EAAE;AAAA,EACzF,SAAS,OAAO;AACd,YAAQ,MAAM,sDAAsD,KAAK;AAAA,EAC3E;AACF;","names":[]}
1
+ {"version":3,"file":"linkedin-conversions-api.cjs","names":["getFirst","IGNORED_EVENTS"],"sources":["../../src/server/linkedin-conversions-api.ts"],"sourcesContent":["/**\n * Conversions API Payload Builder: https://www.linkedin.com/developers/payload-builder\n * https://learn.microsoft.com/en-us/linkedin/marketing/conversions/conversions-overview?view=li-lms-2025-09\n */\nimport { createHash } from 'node:crypto';\nimport { fetch } from '@shware/utils';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport type { TrackEvent, UserProvidedData } from '../track/types';\nimport { getFirst } from '../utils/field';\n\ntype UserIdType =\n | 'SHA256_EMAIL'\n | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID'\n | 'ACXIOM_ID'\n | 'ORACLE_MOAT_ID';\n\nexport interface CreateLinkedinEventDTO {\n /**\n * For any conversion that you want to send through multiple methods, such as Insight Tag and\n * Conversions API, you must create a conversion rule for each data source (browser and server).\n * Then, you can implement a logic to pick up the eventId from the browser and send it with the\n * corresponding event from your server. If we receive an Insight Tag event and a Conversions API\n * event from the same account with the same eventId, we discard the Conversions API event and\n * count only the Insight Tag event in campaign reporting.\n */\n eventId?: string;\n\n /**\n * Replace <id> with the conversion ID extracted when creating the conversion rule\n * (e.g. urn:lla:llaPartnerConversion:<id>).\n */\n conversion: `urn:lla:llaPartnerConversion:${number}`;\n\n /** Epoch timestamp in milliseconds at which the conversion event happened. */\n conversionHappenedAt: number;\n conversionValue: { currencyCode: string; amount: string };\n user: {\n userIds: { idType: UserIdType; idValue: string }[];\n userInfo?: {\n firstName?: string;\n lastName?: string;\n companyName?: string;\n countryCode?: string;\n title?: string;\n };\n\n /**\n * The maximum supported size of the list is 1 at the moment. If the list contains multiple\n * values, only the first value will be used.\n */\n externalIds?: [string, ...string[]];\n\n /**\n * This is generated when users submit the Linkedin Lead-gen form\n * (e.g. urn:li:leadGenFormResponse:<id>).\n */\n lead?: `urn:li:leadGenFormResponse:${string}`;\n };\n}\n\nexport interface CreateMultipleLinkedinEventsDTO {\n elements: CreateLinkedinEventDTO[];\n}\n\nexport type LinkedinConversionConfig = Record<Lowercase<string>, number>;\n\nexport async function sendEvents(\n accessToken: string,\n config: LinkedinConversionConfig,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n events: TrackEvent<any>[],\n data: UserProvidedData = {}\n) {\n const eventNames = Object.keys(config);\n const address = getFirst(data.address);\n const userIds: { idType: UserIdType; idValue: string }[] = [];\n const externalIds: [string, ...string[]] | undefined = data.user_id ? [data.user_id] : undefined;\n const userInfo =\n address && address.first_name && address.last_name\n ? {\n firstName: address.first_name,\n lastName: address.last_name,\n countryCode: address.country,\n }\n : undefined;\n\n if (data.email) {\n const email = getFirst(data.email);\n if (email)\n userIds.push({\n idType: 'SHA256_EMAIL',\n idValue: createHash('sha256').update(email).digest('hex'),\n });\n }\n\n const dto: CreateMultipleLinkedinEventsDTO = {\n elements: events\n .filter((event) => eventNames.includes(event.name) && !IGNORED_EVENTS.includes(event.name))\n .map((event) => ({\n eventId: event.id,\n conversion: `urn:lla:llaPartnerConversion:${config[event.name]}`,\n conversionHappenedAt: Date.now(),\n conversionValue: {\n currencyCode: event.properties?.currency?.toUpperCase() ?? 'USD',\n amount: event.properties?.value?.toString() ?? '0',\n },\n user: {\n userIds: event.tags.li_fat_id\n ? [\n {\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: event.tags.li_fat_id,\n },\n ...userIds,\n ]\n : userIds,\n userInfo,\n externalIds,\n },\n })),\n };\n\n if (dto.elements.length === 0) return;\n try {\n const response = await fetch('https://api.linkedin.com/rest/conversionEvents', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'LinkedIn-Version': '202509',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n },\n body: JSON.stringify(dto),\n });\n\n if (response.ok) return;\n const { status } = response;\n const message = await response.text();\n console.error(`Failed to send LinkedIn conversion, status: ${status}, body: ${message}`);\n } catch (error) {\n console.error('Failed to send LinkedIn conversion, network error:', error);\n }\n}\n"],"mappings":";;;;;;;;;;AAkEA,eAAsB,WACpB,aACA,QAEA,QACA,OAAyB,CAAC,GAC1B;CACA,MAAM,aAAa,OAAO,KAAK,MAAM;CACrC,MAAM,UAAUA,oBAAAA,SAAS,KAAK,OAAO;CACrC,MAAM,UAAqD,CAAC;CAC5D,MAAM,cAAiD,KAAK,UAAU,CAAC,KAAK,OAAO,IAAI,KAAA;CACvF,MAAM,WACJ,WAAW,QAAQ,cAAc,QAAQ,YACrC;EACE,WAAW,QAAQ;EACnB,UAAU,QAAQ;EAClB,aAAa,QAAQ;CACvB,IACA,KAAA;CAEN,IAAI,KAAK,OAAO;EACd,MAAM,QAAQA,oBAAAA,SAAS,KAAK,KAAK;EACjC,IAAI,OACF,QAAQ,KAAK;GACX,QAAQ;GACR,UAAA,GAAA,YAAA,WAAA,CAAoB,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;EAC1D,CAAC;CACL;CAEA,MAAM,MAAuC,EAC3C,UAAU,OACP,QAAQ,UAAU,WAAW,SAAS,MAAM,IAAI,KAAK,CAACC,qCAAAA,eAAe,SAAS,MAAM,IAAI,CAAC,CAAC,CAC1F,KAAK,WAAW;EACf,SAAS,MAAM;EACf,YAAY,gCAAgC,OAAO,MAAM;EACzD,sBAAsB,KAAK,IAAI;EAC/B,iBAAiB;GACf,cAAc,MAAM,YAAY,UAAU,YAAY,KAAK;GAC3D,QAAQ,MAAM,YAAY,OAAO,SAAS,KAAK;EACjD;EACA,MAAM;GACJ,SAAS,MAAM,KAAK,YAChB,CACE;IACE,QAAQ;IACR,SAAS,MAAM,KAAK;GACtB,GACA,GAAG,OACL,IACA;GACJ;GACA;EACF;CACF,EAAE,EACN;CAEA,IAAI,IAAI,SAAS,WAAW,GAAG;CAC/B,IAAI;EACF,MAAM,WAAW,OAAA,GAAA,cAAA,MAAA,CAAY,kDAAkD;GAC7E,QAAQ;GACR,SAAS;IACP,eAAe,UAAU;IACzB,gBAAgB;IAChB,oBAAoB;IACpB,6BAA6B;IAC7B,mBAAmB;GACrB;GACA,MAAM,KAAK,UAAU,GAAG;EAC1B,CAAC;EAED,IAAI,SAAS,IAAI;EACjB,MAAM,EAAE,WAAW;EACnB,MAAM,UAAU,MAAM,SAAS,KAAK;EACpC,QAAQ,MAAM,+CAA+C,OAAO,UAAU,SAAS;CACzF,SAAS,OAAO;EACd,QAAQ,MAAM,sDAAsD,KAAK;CAC3E;AACF"}
@@ -1,56 +1,56 @@
1
- import { TrackEvent, UserProvidedData } from '../track/types.cjs';
2
- import '../track/gtag.cjs';
3
-
1
+ import { TrackEvent, UserProvidedData } from "../track/types.cjs";
2
+ //#region src/server/linkedin-conversions-api.d.ts
4
3
  type UserIdType = 'SHA256_EMAIL' | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID' | 'ACXIOM_ID' | 'ORACLE_MOAT_ID';
5
4
  interface CreateLinkedinEventDTO {
5
+ /**
6
+ * For any conversion that you want to send through multiple methods, such as Insight Tag and
7
+ * Conversions API, you must create a conversion rule for each data source (browser and server).
8
+ * Then, you can implement a logic to pick up the eventId from the browser and send it with the
9
+ * corresponding event from your server. If we receive an Insight Tag event and a Conversions API
10
+ * event from the same account with the same eventId, we discard the Conversions API event and
11
+ * count only the Insight Tag event in campaign reporting.
12
+ */
13
+ eventId?: string;
14
+ /**
15
+ * Replace <id> with the conversion ID extracted when creating the conversion rule
16
+ * (e.g. urn:lla:llaPartnerConversion:<id>).
17
+ */
18
+ conversion: `urn:lla:llaPartnerConversion:${number}`;
19
+ /** Epoch timestamp in milliseconds at which the conversion event happened. */
20
+ conversionHappenedAt: number;
21
+ conversionValue: {
22
+ currencyCode: string;
23
+ amount: string;
24
+ };
25
+ user: {
26
+ userIds: {
27
+ idType: UserIdType;
28
+ idValue: string;
29
+ }[];
30
+ userInfo?: {
31
+ firstName?: string;
32
+ lastName?: string;
33
+ companyName?: string;
34
+ countryCode?: string;
35
+ title?: string;
36
+ };
6
37
  /**
7
- * For any conversion that you want to send through multiple methods, such as Insight Tag and
8
- * Conversions API, you must create a conversion rule for each data source (browser and server).
9
- * Then, you can implement a logic to pick up the eventId from the browser and send it with the
10
- * corresponding event from your server. If we receive an Insight Tag event and a Conversions API
11
- * event from the same account with the same eventId, we discard the Conversions API event and
12
- * count only the Insight Tag event in campaign reporting.
38
+ * The maximum supported size of the list is 1 at the moment. If the list contains multiple
39
+ * values, only the first value will be used.
13
40
  */
14
- eventId?: string;
41
+ externalIds?: [string, ...string[]];
15
42
  /**
16
- * Replace <id> with the conversion ID extracted when creating the conversion rule
17
- * (e.g. urn:lla:llaPartnerConversion:<id>).
43
+ * This is generated when users submit the Linkedin Lead-gen form
44
+ * (e.g. urn:li:leadGenFormResponse:<id>).
18
45
  */
19
- conversion: `urn:lla:llaPartnerConversion:${number}`;
20
- /** Epoch timestamp in milliseconds at which the conversion event happened. */
21
- conversionHappenedAt: number;
22
- conversionValue: {
23
- currencyCode: string;
24
- amount: string;
25
- };
26
- user: {
27
- userIds: {
28
- idType: UserIdType;
29
- idValue: string;
30
- }[];
31
- userInfo?: {
32
- firstName?: string;
33
- lastName?: string;
34
- companyName?: string;
35
- countryCode?: string;
36
- title?: string;
37
- };
38
- /**
39
- * The maximum supported size of the list is 1 at the moment. If the list contains multiple
40
- * values, only the first value will be used.
41
- */
42
- externalIds?: [string, ...string[]];
43
- /**
44
- * This is generated when users submit the Linkedin Lead-gen form
45
- * (e.g. urn:li:leadGenFormResponse:<id>).
46
- */
47
- lead?: `urn:li:leadGenFormResponse:${string}`;
48
- };
46
+ lead?: `urn:li:leadGenFormResponse:${string}`;
47
+ };
49
48
  }
50
49
  interface CreateMultipleLinkedinEventsDTO {
51
- elements: CreateLinkedinEventDTO[];
50
+ elements: CreateLinkedinEventDTO[];
52
51
  }
53
52
  type LinkedinConversionConfig = Record<Lowercase<string>, number>;
54
53
  declare function sendEvents(accessToken: string, config: LinkedinConversionConfig, events: TrackEvent<any>[], data?: UserProvidedData): Promise<void>;
55
-
56
- export { type CreateLinkedinEventDTO, type CreateMultipleLinkedinEventsDTO, type LinkedinConversionConfig, sendEvents };
54
+ //#endregion
55
+ export { CreateLinkedinEventDTO, CreateMultipleLinkedinEventsDTO, LinkedinConversionConfig, sendEvents };
56
+ //# sourceMappingURL=linkedin-conversions-api.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkedin-conversions-api.d.cts","names":[],"sources":["../../src/server/linkedin-conversions-api.ts"],"mappings":";;KAUK;UAMY;;;;;;;;;EASf;;;;;EAMA;;EAGA;EACA;IAAmB;IAAsB;;EACzC;IACE;MAAW,QAAQ;MAAY;;IAC/B;MACE;MACA;MACA;MACA;MACA;;;;;;IAOF;;;;;IAMA;;;UAIa;EACf,UAAU;;KAGA,2BAA2B,OAAO;iBAExB,WACpB,qBACA,QAAQ,0BAER,QAAQ,mBACR,OAAM,mBAAqB"}
@@ -0,0 +1,56 @@
1
+ import { TrackEvent, UserProvidedData } from "../track/types.mjs";
2
+ //#region src/server/linkedin-conversions-api.d.ts
3
+ type UserIdType = 'SHA256_EMAIL' | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID' | 'ACXIOM_ID' | 'ORACLE_MOAT_ID';
4
+ interface CreateLinkedinEventDTO {
5
+ /**
6
+ * For any conversion that you want to send through multiple methods, such as Insight Tag and
7
+ * Conversions API, you must create a conversion rule for each data source (browser and server).
8
+ * Then, you can implement a logic to pick up the eventId from the browser and send it with the
9
+ * corresponding event from your server. If we receive an Insight Tag event and a Conversions API
10
+ * event from the same account with the same eventId, we discard the Conversions API event and
11
+ * count only the Insight Tag event in campaign reporting.
12
+ */
13
+ eventId?: string;
14
+ /**
15
+ * Replace <id> with the conversion ID extracted when creating the conversion rule
16
+ * (e.g. urn:lla:llaPartnerConversion:<id>).
17
+ */
18
+ conversion: `urn:lla:llaPartnerConversion:${number}`;
19
+ /** Epoch timestamp in milliseconds at which the conversion event happened. */
20
+ conversionHappenedAt: number;
21
+ conversionValue: {
22
+ currencyCode: string;
23
+ amount: string;
24
+ };
25
+ user: {
26
+ userIds: {
27
+ idType: UserIdType;
28
+ idValue: string;
29
+ }[];
30
+ userInfo?: {
31
+ firstName?: string;
32
+ lastName?: string;
33
+ companyName?: string;
34
+ countryCode?: string;
35
+ title?: string;
36
+ };
37
+ /**
38
+ * The maximum supported size of the list is 1 at the moment. If the list contains multiple
39
+ * values, only the first value will be used.
40
+ */
41
+ externalIds?: [string, ...string[]];
42
+ /**
43
+ * This is generated when users submit the Linkedin Lead-gen form
44
+ * (e.g. urn:li:leadGenFormResponse:<id>).
45
+ */
46
+ lead?: `urn:li:leadGenFormResponse:${string}`;
47
+ };
48
+ }
49
+ interface CreateMultipleLinkedinEventsDTO {
50
+ elements: CreateLinkedinEventDTO[];
51
+ }
52
+ type LinkedinConversionConfig = Record<Lowercase<string>, number>;
53
+ declare function sendEvents(accessToken: string, config: LinkedinConversionConfig, events: TrackEvent<any>[], data?: UserProvidedData): Promise<void>;
54
+ //#endregion
55
+ export { CreateLinkedinEventDTO, CreateMultipleLinkedinEventsDTO, LinkedinConversionConfig, sendEvents };
56
+ //# sourceMappingURL=linkedin-conversions-api.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkedin-conversions-api.d.mts","names":[],"sources":["../../src/server/linkedin-conversions-api.ts"],"mappings":";;KAUK;UAMY;;;;;;;;;EASf;;;;;EAMA;;EAGA;EACA;IAAmB;IAAsB;;EACzC;IACE;MAAW,QAAQ;MAAY;;IAC/B;MACE;MACA;MACA;MACA;MACA;;;;;;IAOF;;;;;IAMA;;;UAIa;EACf,UAAU;;KAGA,2BAA2B,OAAO;iBAExB,WACpB,qBACA,QAAQ,0BAER,QAAQ,mBACR,OAAM,mBAAqB"}
@@ -1,73 +1,68 @@
1
- // src/server/linkedin-conversions-api.ts
2
- import { createHash } from "crypto";
3
- import { fetch } from "@shware/utils";
4
1
  import { IGNORED_EVENTS } from "../third-parties/ignored-events.mjs";
5
2
  import { getFirst } from "../utils/field.mjs";
3
+ import { fetch } from "@shware/utils";
4
+ import { createHash } from "node:crypto";
5
+ //#region src/server/linkedin-conversions-api.ts
6
+ /**
7
+ * Conversions API Payload Builder: https://www.linkedin.com/developers/payload-builder
8
+ * https://learn.microsoft.com/en-us/linkedin/marketing/conversions/conversions-overview?view=li-lms-2025-09
9
+ */
6
10
  async function sendEvents(accessToken, config, events, data = {}) {
7
- const eventNames = Object.keys(config);
8
- const address = getFirst(data.address);
9
- const userIds = [];
10
- const externalIds = data.user_id ? [data.user_id] : void 0;
11
- const userInfo = address && address.first_name && address.last_name ? {
12
- firstName: address.first_name,
13
- lastName: address.last_name,
14
- countryCode: address.country
15
- } : void 0;
16
- if (data.email) {
17
- const email = getFirst(data.email);
18
- if (email)
19
- userIds.push({
20
- idType: "SHA256_EMAIL",
21
- idValue: createHash("sha256").update(email).digest("hex")
22
- });
23
- }
24
- const dto = {
25
- elements: events.filter((event) => eventNames.includes(event.name) && !IGNORED_EVENTS.includes(event.name)).map((event) => {
26
- var _a, _b, _c, _d;
27
- return {
28
- eventId: event.id,
29
- conversion: `urn:lla:llaPartnerConversion:${config[event.name]}`,
30
- conversionHappenedAt: Date.now(),
31
- conversionValue: {
32
- currencyCode: ((_b = (_a = event.properties) == null ? void 0 : _a.currency) == null ? void 0 : _b.toUpperCase()) ?? "USD",
33
- amount: ((_d = (_c = event.properties) == null ? void 0 : _c.value) == null ? void 0 : _d.toString()) ?? "0"
34
- },
35
- user: {
36
- userIds: event.tags.li_fat_id ? [
37
- {
38
- idType: "LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID",
39
- idValue: event.tags.li_fat_id
40
- },
41
- ...userIds
42
- ] : userIds,
43
- userInfo,
44
- externalIds
45
- }
46
- };
47
- })
48
- };
49
- if (dto.elements.length === 0) return;
50
- try {
51
- const response = await fetch("https://api.linkedin.com/rest/conversionEvents", {
52
- method: "POST",
53
- headers: {
54
- Authorization: `Bearer ${accessToken}`,
55
- "Content-Type": "application/json",
56
- "LinkedIn-Version": "202509",
57
- "X-Restli-Protocol-Version": "2.0.0",
58
- "X-RestLi-Method": "BATCH_CREATE"
59
- },
60
- body: JSON.stringify(dto)
61
- });
62
- if (response.ok) return;
63
- const { status } = response;
64
- const message = await response.text();
65
- console.error(`Failed to send LinkedIn conversion, status: ${status}, body: ${message}`);
66
- } catch (error) {
67
- console.error("Failed to send LinkedIn conversion, network error:", error);
68
- }
11
+ const eventNames = Object.keys(config);
12
+ const address = getFirst(data.address);
13
+ const userIds = [];
14
+ const externalIds = data.user_id ? [data.user_id] : void 0;
15
+ const userInfo = address && address.first_name && address.last_name ? {
16
+ firstName: address.first_name,
17
+ lastName: address.last_name,
18
+ countryCode: address.country
19
+ } : void 0;
20
+ if (data.email) {
21
+ const email = getFirst(data.email);
22
+ if (email) userIds.push({
23
+ idType: "SHA256_EMAIL",
24
+ idValue: createHash("sha256").update(email).digest("hex")
25
+ });
26
+ }
27
+ const dto = { elements: events.filter((event) => eventNames.includes(event.name) && !IGNORED_EVENTS.includes(event.name)).map((event) => ({
28
+ eventId: event.id,
29
+ conversion: `urn:lla:llaPartnerConversion:${config[event.name]}`,
30
+ conversionHappenedAt: Date.now(),
31
+ conversionValue: {
32
+ currencyCode: event.properties?.currency?.toUpperCase() ?? "USD",
33
+ amount: event.properties?.value?.toString() ?? "0"
34
+ },
35
+ user: {
36
+ userIds: event.tags.li_fat_id ? [{
37
+ idType: "LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID",
38
+ idValue: event.tags.li_fat_id
39
+ }, ...userIds] : userIds,
40
+ userInfo,
41
+ externalIds
42
+ }
43
+ })) };
44
+ if (dto.elements.length === 0) return;
45
+ try {
46
+ const response = await fetch("https://api.linkedin.com/rest/conversionEvents", {
47
+ method: "POST",
48
+ headers: {
49
+ Authorization: `Bearer ${accessToken}`,
50
+ "Content-Type": "application/json",
51
+ "LinkedIn-Version": "202509",
52
+ "X-Restli-Protocol-Version": "2.0.0",
53
+ "X-RestLi-Method": "BATCH_CREATE"
54
+ },
55
+ body: JSON.stringify(dto)
56
+ });
57
+ if (response.ok) return;
58
+ const { status } = response;
59
+ const message = await response.text();
60
+ console.error(`Failed to send LinkedIn conversion, status: ${status}, body: ${message}`);
61
+ } catch (error) {
62
+ console.error("Failed to send LinkedIn conversion, network error:", error);
63
+ }
69
64
  }
70
- export {
71
- sendEvents
72
- };
65
+ //#endregion
66
+ export { sendEvents };
67
+
73
68
  //# sourceMappingURL=linkedin-conversions-api.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server/linkedin-conversions-api.ts"],"sourcesContent":["/**\n * Conversions API Payload Builder: https://www.linkedin.com/developers/payload-builder\n * https://learn.microsoft.com/en-us/linkedin/marketing/conversions/conversions-overview?view=li-lms-2025-09\n */\nimport { createHash } from 'node:crypto';\nimport { fetch } from '@shware/utils';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport type { TrackEvent, UserProvidedData } from '../track/types';\nimport { getFirst } from '../utils/field';\n\ntype UserIdType =\n | 'SHA256_EMAIL'\n | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID'\n | 'ACXIOM_ID'\n | 'ORACLE_MOAT_ID';\n\nexport interface CreateLinkedinEventDTO {\n /**\n * For any conversion that you want to send through multiple methods, such as Insight Tag and\n * Conversions API, you must create a conversion rule for each data source (browser and server).\n * Then, you can implement a logic to pick up the eventId from the browser and send it with the\n * corresponding event from your server. If we receive an Insight Tag event and a Conversions API\n * event from the same account with the same eventId, we discard the Conversions API event and\n * count only the Insight Tag event in campaign reporting.\n */\n eventId?: string;\n\n /**\n * Replace <id> with the conversion ID extracted when creating the conversion rule\n * (e.g. urn:lla:llaPartnerConversion:<id>).\n */\n conversion: `urn:lla:llaPartnerConversion:${number}`;\n\n /** Epoch timestamp in milliseconds at which the conversion event happened. */\n conversionHappenedAt: number;\n conversionValue: { currencyCode: string; amount: string };\n user: {\n userIds: { idType: UserIdType; idValue: string }[];\n userInfo?: {\n firstName?: string;\n lastName?: string;\n companyName?: string;\n countryCode?: string;\n title?: string;\n };\n\n /**\n * The maximum supported size of the list is 1 at the moment. If the list contains multiple\n * values, only the first value will be used.\n */\n externalIds?: [string, ...string[]];\n\n /**\n * This is generated when users submit the Linkedin Lead-gen form\n * (e.g. urn:li:leadGenFormResponse:<id>).\n */\n lead?: `urn:li:leadGenFormResponse:${string}`;\n };\n}\n\nexport interface CreateMultipleLinkedinEventsDTO {\n elements: CreateLinkedinEventDTO[];\n}\n\nexport type LinkedinConversionConfig = Record<Lowercase<string>, number>;\n\nexport async function sendEvents(\n accessToken: string,\n config: LinkedinConversionConfig,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n events: TrackEvent<any>[],\n data: UserProvidedData = {}\n) {\n const eventNames = Object.keys(config);\n const address = getFirst(data.address);\n const userIds: { idType: UserIdType; idValue: string }[] = [];\n const externalIds: [string, ...string[]] | undefined = data.user_id ? [data.user_id] : undefined;\n const userInfo =\n address && address.first_name && address.last_name\n ? {\n firstName: address.first_name,\n lastName: address.last_name,\n countryCode: address.country,\n }\n : undefined;\n\n if (data.email) {\n const email = getFirst(data.email);\n if (email)\n userIds.push({\n idType: 'SHA256_EMAIL',\n idValue: createHash('sha256').update(email).digest('hex'),\n });\n }\n\n const dto: CreateMultipleLinkedinEventsDTO = {\n elements: events\n .filter((event) => eventNames.includes(event.name) && !IGNORED_EVENTS.includes(event.name))\n .map((event) => ({\n eventId: event.id,\n conversion: `urn:lla:llaPartnerConversion:${config[event.name]}`,\n conversionHappenedAt: Date.now(),\n conversionValue: {\n currencyCode: event.properties?.currency?.toUpperCase() ?? 'USD',\n amount: event.properties?.value?.toString() ?? '0',\n },\n user: {\n userIds: event.tags.li_fat_id\n ? [\n {\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: event.tags.li_fat_id,\n },\n ...userIds,\n ]\n : userIds,\n userInfo,\n externalIds,\n },\n })),\n };\n\n if (dto.elements.length === 0) return;\n try {\n const response = await fetch('https://api.linkedin.com/rest/conversionEvents', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'LinkedIn-Version': '202509',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n },\n body: JSON.stringify(dto),\n });\n\n if (response.ok) return;\n const { status } = response;\n const message = await response.text();\n console.error(`Failed to send LinkedIn conversion, status: ${status}, body: ${message}`);\n } catch (error) {\n console.error('Failed to send LinkedIn conversion, network error:', error);\n }\n}\n"],"mappings":";AAIA,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AACtB,SAAS,sBAAsB;AAE/B,SAAS,gBAAgB;AA0DzB,eAAsB,WACpB,aACA,QAEA,QACA,OAAyB,CAAC,GAC1B;AACA,QAAM,aAAa,OAAO,KAAK,MAAM;AACrC,QAAM,UAAU,SAAS,KAAK,OAAO;AACrC,QAAM,UAAqD,CAAC;AAC5D,QAAM,cAAiD,KAAK,UAAU,CAAC,KAAK,OAAO,IAAI;AACvF,QAAM,WACJ,WAAW,QAAQ,cAAc,QAAQ,YACrC;AAAA,IACE,WAAW,QAAQ;AAAA,IACnB,UAAU,QAAQ;AAAA,IAClB,aAAa,QAAQ;AAAA,EACvB,IACA;AAEN,MAAI,KAAK,OAAO;AACd,UAAM,QAAQ,SAAS,KAAK,KAAK;AACjC,QAAI;AACF,cAAQ,KAAK;AAAA,QACX,QAAQ;AAAA,QACR,SAAS,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAAA,MAC1D,CAAC;AAAA,EACL;AAEA,QAAM,MAAuC;AAAA,IAC3C,UAAU,OACP,OAAO,CAAC,UAAU,WAAW,SAAS,MAAM,IAAI,KAAK,CAAC,eAAe,SAAS,MAAM,IAAI,CAAC,EACzF,IAAI,CAAC,UAAO;AAlGnB;AAkGuB;AAAA,QACf,SAAS,MAAM;AAAA,QACf,YAAY,gCAAgC,OAAO,MAAM,IAAI,CAAC;AAAA,QAC9D,sBAAsB,KAAK,IAAI;AAAA,QAC/B,iBAAiB;AAAA,UACf,gBAAc,iBAAM,eAAN,mBAAkB,aAAlB,mBAA4B,kBAAiB;AAAA,UAC3D,UAAQ,iBAAM,eAAN,mBAAkB,UAAlB,mBAAyB,eAAc;AAAA,QACjD;AAAA,QACA,MAAM;AAAA,UACJ,SAAS,MAAM,KAAK,YAChB;AAAA,YACE;AAAA,cACE,QAAQ;AAAA,cACR,SAAS,MAAM,KAAK;AAAA,YACtB;AAAA,YACA,GAAG;AAAA,UACL,IACA;AAAA,UACJ;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,KAAE;AAAA,EACN;AAEA,MAAI,IAAI,SAAS,WAAW,EAAG;AAC/B,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,kDAAkD;AAAA,MAC7E,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,WAAW;AAAA,QACpC,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,QACpB,6BAA6B;AAAA,QAC7B,mBAAmB;AAAA,MACrB;AAAA,MACA,MAAM,KAAK,UAAU,GAAG;AAAA,IAC1B,CAAC;AAED,QAAI,SAAS,GAAI;AACjB,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,UAAU,MAAM,SAAS,KAAK;AACpC,YAAQ,MAAM,+CAA+C,MAAM,WAAW,OAAO,EAAE;AAAA,EACzF,SAAS,OAAO;AACd,YAAQ,MAAM,sDAAsD,KAAK;AAAA,EAC3E;AACF;","names":[]}
1
+ {"version":3,"file":"linkedin-conversions-api.mjs","names":[],"sources":["../../src/server/linkedin-conversions-api.ts"],"sourcesContent":["/**\n * Conversions API Payload Builder: https://www.linkedin.com/developers/payload-builder\n * https://learn.microsoft.com/en-us/linkedin/marketing/conversions/conversions-overview?view=li-lms-2025-09\n */\nimport { createHash } from 'node:crypto';\nimport { fetch } from '@shware/utils';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport type { TrackEvent, UserProvidedData } from '../track/types';\nimport { getFirst } from '../utils/field';\n\ntype UserIdType =\n | 'SHA256_EMAIL'\n | 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID'\n | 'ACXIOM_ID'\n | 'ORACLE_MOAT_ID';\n\nexport interface CreateLinkedinEventDTO {\n /**\n * For any conversion that you want to send through multiple methods, such as Insight Tag and\n * Conversions API, you must create a conversion rule for each data source (browser and server).\n * Then, you can implement a logic to pick up the eventId from the browser and send it with the\n * corresponding event from your server. If we receive an Insight Tag event and a Conversions API\n * event from the same account with the same eventId, we discard the Conversions API event and\n * count only the Insight Tag event in campaign reporting.\n */\n eventId?: string;\n\n /**\n * Replace <id> with the conversion ID extracted when creating the conversion rule\n * (e.g. urn:lla:llaPartnerConversion:<id>).\n */\n conversion: `urn:lla:llaPartnerConversion:${number}`;\n\n /** Epoch timestamp in milliseconds at which the conversion event happened. */\n conversionHappenedAt: number;\n conversionValue: { currencyCode: string; amount: string };\n user: {\n userIds: { idType: UserIdType; idValue: string }[];\n userInfo?: {\n firstName?: string;\n lastName?: string;\n companyName?: string;\n countryCode?: string;\n title?: string;\n };\n\n /**\n * The maximum supported size of the list is 1 at the moment. If the list contains multiple\n * values, only the first value will be used.\n */\n externalIds?: [string, ...string[]];\n\n /**\n * This is generated when users submit the Linkedin Lead-gen form\n * (e.g. urn:li:leadGenFormResponse:<id>).\n */\n lead?: `urn:li:leadGenFormResponse:${string}`;\n };\n}\n\nexport interface CreateMultipleLinkedinEventsDTO {\n elements: CreateLinkedinEventDTO[];\n}\n\nexport type LinkedinConversionConfig = Record<Lowercase<string>, number>;\n\nexport async function sendEvents(\n accessToken: string,\n config: LinkedinConversionConfig,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n events: TrackEvent<any>[],\n data: UserProvidedData = {}\n) {\n const eventNames = Object.keys(config);\n const address = getFirst(data.address);\n const userIds: { idType: UserIdType; idValue: string }[] = [];\n const externalIds: [string, ...string[]] | undefined = data.user_id ? [data.user_id] : undefined;\n const userInfo =\n address && address.first_name && address.last_name\n ? {\n firstName: address.first_name,\n lastName: address.last_name,\n countryCode: address.country,\n }\n : undefined;\n\n if (data.email) {\n const email = getFirst(data.email);\n if (email)\n userIds.push({\n idType: 'SHA256_EMAIL',\n idValue: createHash('sha256').update(email).digest('hex'),\n });\n }\n\n const dto: CreateMultipleLinkedinEventsDTO = {\n elements: events\n .filter((event) => eventNames.includes(event.name) && !IGNORED_EVENTS.includes(event.name))\n .map((event) => ({\n eventId: event.id,\n conversion: `urn:lla:llaPartnerConversion:${config[event.name]}`,\n conversionHappenedAt: Date.now(),\n conversionValue: {\n currencyCode: event.properties?.currency?.toUpperCase() ?? 'USD',\n amount: event.properties?.value?.toString() ?? '0',\n },\n user: {\n userIds: event.tags.li_fat_id\n ? [\n {\n idType: 'LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID',\n idValue: event.tags.li_fat_id,\n },\n ...userIds,\n ]\n : userIds,\n userInfo,\n externalIds,\n },\n })),\n };\n\n if (dto.elements.length === 0) return;\n try {\n const response = await fetch('https://api.linkedin.com/rest/conversionEvents', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n 'LinkedIn-Version': '202509',\n 'X-Restli-Protocol-Version': '2.0.0',\n 'X-RestLi-Method': 'BATCH_CREATE',\n },\n body: JSON.stringify(dto),\n });\n\n if (response.ok) return;\n const { status } = response;\n const message = await response.text();\n console.error(`Failed to send LinkedIn conversion, status: ${status}, body: ${message}`);\n } catch (error) {\n console.error('Failed to send LinkedIn conversion, network error:', error);\n }\n}\n"],"mappings":";;;;;;;;;AAkEA,eAAsB,WACpB,aACA,QAEA,QACA,OAAyB,CAAC,GAC1B;CACA,MAAM,aAAa,OAAO,KAAK,MAAM;CACrC,MAAM,UAAU,SAAS,KAAK,OAAO;CACrC,MAAM,UAAqD,CAAC;CAC5D,MAAM,cAAiD,KAAK,UAAU,CAAC,KAAK,OAAO,IAAI,KAAA;CACvF,MAAM,WACJ,WAAW,QAAQ,cAAc,QAAQ,YACrC;EACE,WAAW,QAAQ;EACnB,UAAU,QAAQ;EAClB,aAAa,QAAQ;CACvB,IACA,KAAA;CAEN,IAAI,KAAK,OAAO;EACd,MAAM,QAAQ,SAAS,KAAK,KAAK;EACjC,IAAI,OACF,QAAQ,KAAK;GACX,QAAQ;GACR,SAAS,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;EAC1D,CAAC;CACL;CAEA,MAAM,MAAuC,EAC3C,UAAU,OACP,QAAQ,UAAU,WAAW,SAAS,MAAM,IAAI,KAAK,CAAC,eAAe,SAAS,MAAM,IAAI,CAAC,CAAC,CAC1F,KAAK,WAAW;EACf,SAAS,MAAM;EACf,YAAY,gCAAgC,OAAO,MAAM;EACzD,sBAAsB,KAAK,IAAI;EAC/B,iBAAiB;GACf,cAAc,MAAM,YAAY,UAAU,YAAY,KAAK;GAC3D,QAAQ,MAAM,YAAY,OAAO,SAAS,KAAK;EACjD;EACA,MAAM;GACJ,SAAS,MAAM,KAAK,YAChB,CACE;IACE,QAAQ;IACR,SAAS,MAAM,KAAK;GACtB,GACA,GAAG,OACL,IACA;GACJ;GACA;EACF;CACF,EAAE,EACN;CAEA,IAAI,IAAI,SAAS,WAAW,GAAG;CAC/B,IAAI;EACF,MAAM,WAAW,MAAM,MAAM,kDAAkD;GAC7E,QAAQ;GACR,SAAS;IACP,eAAe,UAAU;IACzB,gBAAgB;IAChB,oBAAoB;IACpB,6BAA6B;IAC7B,mBAAmB;GACrB;GACA,MAAM,KAAK,UAAU,GAAG;EAC1B,CAAC;EAED,IAAI,SAAS,IAAI;EACjB,MAAM,EAAE,WAAW;EACnB,MAAM,UAAU,MAAM,SAAS,KAAK;EACpC,QAAQ,MAAM,+CAA+C,OAAO,UAAU,SAAS;CACzF,SAAS,OAAO;EACd,QAAQ,MAAM,sDAAsD,KAAK;CAC3E;AACF"}